JVM的垃圾回收存在于堆和元空间(方法区或永久代)中,最多发生在新生代,偶尔发生在老年代,基本不发生在方法区。
对象存活判断:一个对象不被任意的存活对象继续引用时,就已经死亡。
判断对象存活的两种方式:引用计数算法和可达性分析算法。
1.垃圾标记阶段的算法之一:引用计数算法
2.垃圾标记阶段的算法之二:可达性分析(根搜索算法)
3.清除阶段的算法之一:标记-清除算法
当堆中的内存被耗尽时,就会停止整个程序(stop the world),进行标记和清除两项工作。
标记:垃圾回收器从引用根节点开始遍历,标记被引用对象。
清除:垃圾回收器对堆内存进行遍历,发现某个对象无标记,进行回收。
缺点:效率不是很高;进行GC时,需要停止整个应用程序;清理出来的内存不连续。
4.清除阶段的算法之二:复制算法
核心思想
将内存分为两块,每次只使用一块,在GC时将可以遍历到的对象放到内存的另一块中,然后把原先的那部分内存中的对象全部清除。
**优点:**没有标记和清除过程,简单高效。不会出现碎片问题。
**缺点:**需要2倍的内存空间,有一部分内存总是处于空闲状态。
**适合场景:**存活对象少,垃圾对象多。新生代中使用此算法。
5.清除阶段的算法之三:标记-压缩算法
执行过程
**优点:**内存区域可以集中,无碎片;不用内存减半。
**缺点:**效率低;需要STW。
6.对比三种GC算法
7.分代收集算法
年轻代
区域相比老年代较小,生命周期短,存活率低,回收频繁,使用复制算法。
老年代
区域大,生命周期长,存活率高,频率低。
标记-清除和标记-整理的混合实现。