JVM中G1收集器有什么用
这篇文章主要介绍了JVM中G1收集器有什么用,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。
首先看看G1收集器的内存模型
一、GI收集器虽然也是分代收集器,但是在内存结构上却和其他的收集器大相径庭,从这里就可以看出G1是物理上的分区,逻辑上的分代, G1不需要survivorTo做复制。
二、G1拥有Humongous区,是存放巨型对象的区域,巨型对象是当一个区被占到一半以上,也会出现一个区都装不下,这时候就会需要连续的多个分区,寻找一个连续的内存区间是很困难的,如果内存不够或许会造成Full GC。
首先谈谈CMS的缺点:
1.由于并发进行,CMS在收集与应用线程会同时会增加对堆内存的占用,也就是说,CMS必须要在老年代堆内存用尽之前完成垃圾回收,否则CMS回收失败时,将触发担保机制,串行老年代收集器将会以STW(Stop-the-world)的方式进行一次GC,从而造成较大停顿时间;
而在G1中,设计原则是"首先收集尽可能多的垃圾(Garbage First)",G1会优先回收垃圾比例比较高得的区域,而不会等到内存用尽得时候,但是当G1收集器非常忙的时候,内存溢出,也会触发担保机制,就是使用serial old收集器进行一次Full GC。
2.标记清除算法无法整理空间碎片,老年代空间会随着应用时长被逐步耗尽,最后将不得不通过担保机制对堆内存进行压缩。CMS也提供了参数-XX:CMSFullGCsBeForeCompaction(默认0,即每次都进行内存整理)来指定多少次CMS收集之后,进行一次压缩的Full GC。
G1不会产生内存碎片,采用的是标志整理算法
再来看看G1的收集过程:
初始标记:标记从根节点直接可达的对象。这个阶段会伴随一次新生代GC,它是会产生全局停顿的,应用程序在这个阶段必须停止执行。
根区域扫描:由于初始标记必然会伴随一次新生代GC,所以在初始化标记后,eden被清空,并且存活对象被移到survivor区。在这个阶段,将扫描由survivor区直接可达的老年代区域,并标记这些直接可达的对象。这个过程是可以和应用程序并发执行的。但是根区域扫描不能和新生代GC同时发生(因为根区域扫描依赖survivor区的对象,而新生代GC会修改这个区域),故如果恰巧此时需要新生代GC,GC就需要等待根区域扫描结束后才能进行,如果发生这种情况,这次新生代GC的时间就会延长。
并发标记:和CMS类似,并发标记将会扫描并查找整个堆的存活对象,并做好标记。这是一个并发过程,并且这个过程可以被一次新生代GC打断。
重新标记:和CMS一样,重新标记也是会使应用程序停顿,由于在并发标记过程中,应用程序依然运行,因此标记结果可能需要修正,所以在此阶段对上一次标记进行补充。在G1中,这个过程使用SATB(Snapshot-At-The-Begining)算法完成,即G1会在标记之初为存活对象创建一个快照,这个快照有助于加速重新标记的速度。
独占清理:顾名思义,这个阶段会引起停顿。它将计算各个区域的存活对象和GC回收比例并进行排序,识别可供混合回收的区域。在这个阶段,还会更新记忆集。该阶段给出了需要被混合回收的区域并进行了标记,在混合回收阶段,需要这些信息。
并发清理阶段:识别并清理完全空闲的区域。它是并发的清理,不会引起停顿。
三色标记
提到并发标记,我们不得不了解并发标记的三色标记算法。它是描述追踪式回收器的一种有用的方法,利用它可以推演回收器的正确性。
首先,我们将对象分成三种类型的:
黑色:跟对象或者该对象与它的子对象都被扫描(标记完成)。
灰色:对象本身被标记完成,但是还没有扫描完该对象中的子对象
白色:未被扫描的对象。或者是扫描完成后,最终白色对象为不可达对象即为垃圾对象。
感谢你能够认真阅读完这篇文章,希望小编分享的"JVM中G1收集器有什么用"这篇文章对大家有帮助,同时也希望大家多多支持,关注行业资讯频道,更多相关知识等着你来学习!