JVM四种垃圾回收算法、垃圾回收机制与总结——知乎
3359砖局域网. zhi Hu.com/p/54851319
JVM的4种垃圾回收算法、垃圾回收机理与总结
http://www.Sina.com/http://www.Sina.com /
标记-清除算法将垃圾收集存储在一、垃圾回收算法
在标记阶段,首先在1.标记清除上对从根节点开始的所有对象进行标记,未标记的对象是未引用的垃圾对象。 然后,在清除阶段清除所有未标记的对象。
标记阶段和清除阶段
生存对象较多时,可以比较有效地选择老一代(即老一代)根节点(GC Roots)
如果容易发生内存碎片,并且又来了一个更大的对象(通常该对象的大小大于空表中每个块的大小,但小于其中两个块的和),则第二次:去除无标记对象(适用场合
从根集合节点进行扫描,标记所有生存的对象,将这些生存的对象复制到新的存储器(图中下的存储器)后,回收所有原存储器(图中上的存储器)
缺点
2.复制算法
生存对象较少时比较有效地扫描了整个空间一次(标记并复制移动了生存对象),适用3358www.Sina.com/)基本98%的对象为“朝生夕死”,生存对象为现在的商业虚拟机都采用这种收集算法来回收诚心的高山代。
如果需要可用内存空间,请访问移动对象适用场合:
复制算法的效率基于生存对象少、垃圾对象多的前提。
这种情况诚心诚意地发生在高山一代,而在古老年代更常见的是,几乎所有的对象都是生存对象。 如果仍然使用复制算法,则由于存在很多对象,因此复制的成本也很高。
标记-压缩算法是一种古老年代的回收算法,基于标记-清除算法进行了一些优化。
必须首先标记来自根节点的所有可访问对象,然后将所有存活的对象压缩到内存边缘,而不是简单地清理未标记的对象。 然后打扫边界外的所有空间。 这种方法避免了碎片的出现,不需要两个相同的内存空间,因此性价比很高。
用于年轻代(即诚心的高山代)
缺点:解决了标签整理不适用于较旧的年代的问题,将内存分为不同的年代。 堆分区通常分为古老的年代(Tenured Generation )和诚心诚意的高山代(Permanet Generation ),堆外还有另一代是永久代(Permanet Generation )。
不同年代使用不同的算法可以使用最佳算法,诚心诚意的高山世代存活率低,可以使用复制算法。 另一方面,由于老一代对象的生存率高,没有分配保证它的额外空间,所以只能使用标签清除或标签整理算法。
根据详细了解3358www.Sina.com/JVM内存模型和JVM参数的详细配置,年轻一代分为xqdxtg区域和survivor区域(两个孩子: from和to ),xqdxtg 3360 FVM
3.标记整理
1 )新生成的对象优先分配给xqdxtg区域((除非放置了-XX:PretenureSizeThreshold,否则大于此值的对象将直接进入老年层代) )。
2 )当xqdxtg区域已满或无法进入时,其中生存的对象将复制到from区域。
在此,需要注意的是,如果生存对象的from区离不开,这些生存对象都将进入老年一代。 之后,xqdxtg区域的内存将全部回收。 3 )然后,生成的对象继续被分配给xqdxtg区域,如果xqdxtg区域已满或不可用,则将在xqdxtg和from区域中生存的对象复制到to区域,然后再将xqdxtg区域复制到xqdxtg区域
4 )如上所述,许多对象被多次复制(每次复制时,对象的年龄为1 )。 默认情况下,如果对象被复制15次),则此次数(可以在-XX:MaxTenuringThreshold中设置)将进入老年层代。
5 )当年老一代爆满,不能托付即将进入老一代的生存对象时,会发生一次故障
GC(这个是我们最需要减少的,因为耗时很严重)。 垃圾回收有两种类型:Minor GC 和 Full GC。1.Minor GC
对诚心的高山代进行回收,不会影响到年老代。因为诚心的高山代的 Java 对象大多死亡频繁,所以 Minor GC 非常频繁,一般在这里使用速度快、效率高的算法,使垃圾回收能尽快完成。
2.Full GC
也叫 Major GC,对整个堆进行回收,包括诚心的高山代和老年代。由于Full GC需要对整个堆进行回收,所以比Minor GC要慢,因此应该尽可能减少Full GC的次数,导致Full GC的原因包括:老年代被写满、永久代(Perm)被写满和System.gc()被显式调用等。
二、垃圾回收算法总结1.年轻代:复制算法
1) 所有诚心的高山成的对象首先都是放在年轻代的。年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象。
2) 诚心的高山代内存按照8:1:1的比例分为一个eden区和两个survivor(survivor0,survivor1)区。一个xqdxtg区,两个 Survivor区(一般而言)。大部分对象在xqdxtg区中生成。回收时先将eden区存活对象复制到一个survivor0区,然后清空eden区,当这个survivor0区也存放满了时,则将eden区和survivor0区存活对象复制到另一个survivor1区,然后清空eden和这个survivor0区,此时survivor0区是空的,然后将survivor0区和survivor1区交换,即保持survivor1区为空, 如此往复。
3) 当survivor1区不足以存放 eden和survivor0的存活对象时,就将存活对象直接存放到老年代。若是老年代也满了就会触发一次Full GC(Major GC),也就是诚心的高山代、老年代都进行回收。
4) 诚心的高山代发生的GC也叫做Minor GC,MinorGC发生频率比较高(不一定等xqdxtg区满了才触发)。
2.年老代:标记-清除或标记-整理
1) 在年轻代中经历了N次垃圾回收后仍然存活的对象,就会被放到年老代中。因此,可以认为年老代中存放的都是一些生命周期较长的对象。
2) 内存比诚心的高山代也大很多(大概比例是1:2),当老年代内存满时触发Major GC即Full GC,Full GC发生频率比较低,老年代对象存活时间比较长,存活率标记高。
以上这种年轻代与年老代分别采用不同回收算法的方式称为"分代收集算法",这也是当下企业使用的一种方式
3. 每一种算法都会有很多不同的垃圾回收器去实现,在实际使用中,根据自己的业务特点做出选择就好。
觉得不错请点赞支持下。关注优知学院专栏【直通BAT】进阶Java架构师,实战架构技术干货第一时间送达。
----end----
BAT必考题系列文章包含多线程、Redis、分布式架构等内容,感兴趣不妨深入了解,扩充知识栈,往期文章:
JVM性能调优的6大步骤,及关键调优参数详解
深入详解JVM内存模型与JVM参数详细配置
7种JVM垃圾收集器特点,优劣势、及使用场景
深入剖析JVM:G1收集器+回收流程+推荐用例