1.1 判断对象回收的方法
- 引用计数器法
维护一个引用计数器,每当一个对象引用 计数器加一,当为0的时候就回收,无法解决循环引用的问题 - 可达性分析算法 GC Root
从一个根对象向下找,把能找到的对象标记下,等垃圾回收器把没有标记的对象回收掉
1.2 什么对象可以当作GC Root
- 虚拟机栈中的栈帧中的本地变量表引用的对象
- 方法区中常量引用的对象
- 方法区中静态变量引用的对象
- 本地方法栈引用的对象
1.3 什么时候会发生GC
- minorGC
我们首先需要知道JVM内存模型,我们new的对象都放在堆区域中,堆分为年轻代与老年代,年轻代分为Eden 区 From survivor区,To survivor区, 其中他们的比值分别是8:1:1,我们给堆分配内存600M,这个可以通过-Xms -Xmx
控制,那么默认老年代占2/3,那么就是400M,那年轻代就是200M,Eden区160M,Survivor区40M。我们new出的对象就放在Eden区,当Eden区满了,就会发生minor GC。当第一次把Eden区装满后,会把存活的对象放到From区中,然后经过一次GC存活下来得分对象,会在其对象头中的Mark Word 中的GC分代年龄加一,当达到15次的时候会把这个对象放到老年代,当老年代满了之后会触发Full GC。当第二次把Eden区装满后,会对Eden与From区进行回收,把存活的对象放到To中。
1.4 Full GC触发条件
- 调用
System.gc()
函数,建议JVM进行垃圾回收 - 老年代内存空间不够
- 当进行minor gc 时 survivor区内存不够放存活对象的时候会进行老年代空间担保,放到老年代,如果老年代空间不足那么就会进行Full GC.
- 当对象的gc分代年龄大于15后需要放到老年代,这时如果老年代空间不足那么会进行Full GC
- 当survivor区对象相同年龄的对象占据了一半,就会把这些对象放到老年代中,这时如果空间不足,那么会执行Full GC
- 创建的大对象 大数组 会被放到老年代 如果这时候老年代空间不足就会触发
- 方法区空间不足
未完待续