1.垃圾回收之标记算法
对象被判定为垃圾的标准:
没有被其他对象引用
判定对象是否为垃圾的算法:
引用计数算法
可达性分析算法
(1)引用计数算法:
判断对象的引用数量:
通过判断对象的引用数量来决定对象是否可以被回收
每个对象实例都有一个引用计数器,被引用+1,完成引用-1
任何引用计数为0的对象实例都可以被当作垃圾回收
优点:执行效率高,程序执行受影响较小
缺点:无法检测循环引用的情况,导致内存泄露
(2)可达性分析算法
通过判断对象的引用链是否可达来决定对象是否可以被回收
垃圾回收机制会对整理对象图,从GCRoot开始,回收器将访问到的所有变量标记为存活,如图标记为蓝色。灰色的对象表示不可达,这些就是垃圾对象。
可以作为GCROOT的对象:
2.java垃圾回收之回收算法
(1)标记-清除算法:
标记:从根集合进行扫描,对存活的对象进行标记。
清除:对堆内存从头到尾进行线性遍历。回收不可达对象内存。
不足:由于标记-清除算法不需要对对象进行移动,并且仅对不存活的对象进行处理,因此会产生大量不连续的碎片。空间碎片太多,会导致以后分配较大的对象内存时无法找到足够的连续内存。导致不得不提前触发另外一个垃圾回收工作。
(2)复制算法:
小TIP:
复制算法在应对存活率较高的情况时,无法高效处理。所以在老年代一般不采取复制算法,而是采用标记整理算法。
(3)标记整理算法
避免内存的不连续行;
不用设置两块内存互换;
适用于存活率较高的场景;
(4)分代收集算法
年轻代采用复制算法。老年代存活率高采用标记整理算法或者标记-清除算法。
GC的分类:
Minor GC:发生在年轻代,采用复制算法。Java内存申请以及存放都是在此。
Full GC:对老年代的回收伴随着年轻代的回收
年轻代:尽可能快速的收集掉那些生命周期短对象-复制算法
–Eden区:
起源,对象被创建出来时,其内存空间分配在Eden区。
–两个Survivor:
分成from区和to区。from和to是动态变化的。from暂时保存存活对象的,因为会把eden里存活的,以及原from区存活的放入新from区中,所以原来的from变成to区,当前Survivor区变成from区。然后对原from和edon区内存直接全部回收。完成一次Minor GC。当from区不够时,就要借用老年代区间了.
每经历一次回收年龄会+1.
通常年轻代中的eden:from:to=8:1:1
老年代–对象如何晋升到老年代:
1.经过一定的Minor次数依然存活的对象,默认为15次
2.survivor区放不下的对象
3.新生成的大对象(参数设置-XX:+PretenuerSizeThreshold)
老年代:采用标记-清除算法或标记-整理算法
Full GC和Major GC
Major GC:用于回收老年代,执行Major GC之前一定会执行一次minor GC.当老年代空间不足的时候就会执行Major GC.
FULL GC比Minor GC慢,但是执行频率低(10倍以上)
触发Full GC的条件:
分析:永久代空间不足,出现在jdk7及以前。调用System.gc()提醒jvm,最后是否回收由虚拟机决定。