Java 垃圾回收机制
Java 垃圾回收机制
- Garbage Collection 垃圾回收机制是指 JVM 虚拟机自动管理内存的一种机制,通过自动检测识别并回收不再使用的对象(垃圾对象),以达到释放内存空间,提高程序的性能和稳定性
判断垃圾对象的方法
- 引用计数法:给对象添加一个引用计数器,每当有一个引用指向该对象时,计数器加 1,当引用失效时,计数器减 1,所以当计数器为 0 时,表示没有引用指向该对象,说明该对象可以被回收,不过由于它无法处理对象间相互循环引用问题,因此 Java 没有采用引用计数法
- 可达性分析算法:通过一系列称为 GC Roots 的对象(比如栈帧中的局部变量、静态变量等)作为起点,通过遍历 Reference Chain 引用链向下搜索,标记可达对象,清除不可达对象,于是垃圾对象就会被回收,这是 Java 采用的主流判断方式
GC Roots
- 虚拟机栈内栈帧中的局部变量
- 本地方法栈内的对象
- 堆内的静态变量和字符串常量池中的对象
垃圾回收算法
- 标记-清除算法(Mark-Sweep):先标记所有被引用的对象(可达对象),然后统一回收清除不可达对象,缺点是容易产生大量内存碎片
- 复制算法(Copying):将内存分为大小相等的两块交替使用,每次只使用其中一块,当一块内存用完时,将存活对象复制到另一块内存区域,然后清除原内存区域,缺点是空间利用率较低
- 标记-整理算法(Mark-Compact):先标记存活对象(可达对象),然后将所有存活对象向内存一端整理移动,最后直接清理边界外的内存(实现内存碎片压缩)
分代收集
- 根据对象生命周期长短采用不同的策略,平衡内存利用率与性能
- 将堆内存划分为 Young Generation 新生代和 Old Generation 老年代,新生代又进一步分为 Eden 伊甸园区和两个 Survivor 幸存者区,即 S0(From Survivor)和 S1(To Survivor),针对不同代的特点采用不同的回收策略
- 新生代:对象存活率低(比如临时变量),采用复制算法
- Eden 伊甸园区:新对象分配的区域
- 两个 Survivor 幸存者区:每次 GC 后存活的对象从 Eden 和 From 中复制到 To,然后交换一下 From 和 To 的角色,保证 Eden 和 From 总是空着的
- 老年代:对象存活率高(比如长生命周期的对象),采用标记-清除或标记-整理算法