引用计数法、可达性算法。
1. 描述
每个对象有一个引用计数器,当对象被引用一次则计数器加1,当对象引用失效一次则计数器减1,对于计数器为0的对象意味着是垃圾对象,可以被GC回收。
2. 优点
3. 缺点
1. 描述
从GC Roots对象作为起始点,利用数学中图论知识,图中可达对象便是存活对象,而不可达对象则是需要回收的垃圾内存。
GC Roots对象包括:
标记清除算法、复制算法、标记整理算法、分代收集算法
分为两个阶段:标记、清除
标记阶段:确定所有需要回收的对象,并做好标记。
清除阶段:将标记阶段确认不可用的对象清除。
缺点:
1. 标记和清除的效率都不高。
2. 会产生大量不连续的内存碎片,空间碎片过多可能导致以后在程序运行过程中需要分配较大对象时,无法为其分配足够大的连续空间,导致不得不提前进行一次垃圾回收。
内存分为两块大小相同的区域,每次只使用其中一块。当垃圾回收时,把存活的对象复制到另一块上,然后把这块内存整个清理掉。交换两个内存的角色,完成垃圾回收。
缺点:
1. 需要浪费额外的空间作为复制区。
2. 不适用于存活对象较多的场合,如老年代。当对象的存活率较高时,复制算法效率会下降。
先标记出所有存活的对象,把存活的对象往一端移动,然后直接回收边界外的空间。
特点:
适用于存活对象较多的场合,如老年代。
效率:复制 > 标记整理 > 标记清除(此处的效率只是简单的对比时间复杂度,实际情况并非如此)
内存利用率:标记整理 > 标记清除 > 复制
内存整齐度: 复制 = 标记整理 > 标记清除
分代收集算法根据对象的存活时间把内存分为新生代和老年代。 根据分代对象的特点,每个代使用不同的垃圾回收算法。
新生代:每次垃圾回收都会有大量对象死去,只有少量存活,因此选择复制算法。
老年代:因为对象存活率高、没有额外空间为他们进行分配担保,因此选择标记-清除或标记-整理算法。
新生代Young:存放新创建的对象,对象的生命周期非常短,几乎用完就可以回收,也叫eden区。
老年代Old:young区多次回收后存活下来的对象将被移进Old区。
永久代Permanent:主要存储加载的类信息,生命周期长,几乎不会被回收。
老年代 + 永久代 约占堆的2/3,新生代约占堆的1/3。
新生代又被分为eden、from survivor、to survivor(8:1:1)。JVM每次都只使用eden和其中一块survivor来为对象进行服务,所以无论什么时候,都会有一块survivor空间,因此新生代实际可用空间为90%。
当对象在eden中创建,经历过一次minor gc后仍然存活,并且能够被to survivor所容纳,则使用复制算法将这些存活的对象复制到to survivor区,然后清理掉eden和from survivor区,并将这些存活的对象年龄+1,以后对象在survivor每熬过一次minor gc,年龄便+1,当对象达到某个值时(默认为15,通过设置参数-xx:maxtenuringThreshold来设置),这些对象就会被移动到老年代。当一些较大的对象(需要分配连续的内存空间)则直接进入老年代。
原文:https://www.cnblogs.com/th2009yu/p/14564364.html