和传统的 CMS 等垃圾器回收器相比 G1 具有哪些特性?

G1 收集是相比于其他收集器(可见 上一篇文章),可以独立运行,同时做到了并发和并行。下面看一下它是如何实现的。之前介绍的几组垃圾收集器组合,都有几个共同点:

年轻代、老年代是独立且连续的内存块;
年轻代收集使用单eden、双survivor进行复制算法;
老年代收集必须扫描整个老年代区域;
都是以尽可能少而块地执行GC为设计原则。

虽然分区使得内存分配不再要求紧凑的内存空间,化整为零
G1垃圾收集器也是以关注延迟为目标、服务器端应用的垃圾收集器,被HotSpot团队寄予取代CMS的使命,也是一个非常具有调优潜力的垃圾收集器。虽然G1也有类似CMS的收集动作:初始标记、并发标记、重新标记、清除、转移回收,并且也以一个串行收集器做担保机制,但单纯地以类似前三种的过程描述显得并不是很妥当。

G1一般推荐使用它的默认设置,然后设置一个停顿时间和最大堆内存的目标。
G1跟别的收集器不一样,G1默认配置的目标既不是最大化吞吐量也不是最小化停顿时间,而是使用时间相对较短的停顿来达到很高的吞吐量。 但是,G1的这种增量回收内存和停顿时间的控制机制不管是对应用线程还是对内存回收的效率都会导致一些额外的开销。

如果你更想要高的吞吐量,那就设置相对宽松的停顿时间的目标(用 -XX:MaxGCPauseMillis)或者是提供更大的堆内存。如果停顿时间更重要,那就修改停顿时间的目标。要避免使用 -Xmn, -XX:NewRatio 这样的参数来限制young区的大小,因为G1主要是靠自适应调整young区的大小来满足停顿时间的目标的。如果设置了young区的大小,那就会覆盖掉并且会禁用掉对停顿时间的控制。

https://www.cnblogs.com/Benjious/p/10304799.html




https://blog.csdn.net/w2009211777/article/details/123864460



以上三组收集器有很大不同:

G1的设计原则是"首先收集尽可能多的垃圾(Garbage First)"。因此,G1并不会等内存耗尽(串行、并行)或者快耗尽(CMS)的时候开始垃圾收集,而是在内部采用了启发式算法,在老年代找出具有高收集收益的分区进行收集。同时G1可以根据用户设置的暂停时间目标自动调整年轻代和总堆大小,暂停目标越短年轻代空间越小、总空间就越大;

G1采用内存分区(Region)的思路,将内存划分为一个个相等大小的内存分区,回收时则以分区为单位进行回收,存活的对象复制到另一个空闲分区中。由于都是以相等大小的分区为单位进行操作,因此G1天然就是一种压缩方案(局部压缩);

G1虽然也是分代收集器,但整个内存分区不存在物理上的年轻代与老年代的区别,也不需要完全独立的survivor(to space)堆做复制准备。G1只有逻辑上的分代概念,或者说每个分区都可能随G1的运行在不同代之间前后切换;

G1的收集都是STW的,但年轻代和老年代的收集界限比较模糊,采用了混合(mixed)收集的方式。即每次收集既可能只收集年轻代分区(年轻代收集),也可能在收集年轻代的同时,包含部分老年代分区(混合收集),这样即使堆内存很大时,也可以限制收集范围,从而降低停顿。

https://www.cnblogs.com/Benjious/p/10304799.html



G1和其他收集器截然不同,从分代上看,它仍然属于分代垃圾收集器,也会区分新生代、老年代,仍然有Eden区和Survivor区;从堆结构上看,它并不要求新生代、老年代都连续。作为CMS的长期替代方案,G1使用了分区算法,其特点如下:
    a)并行性:在回收期间,可以由多个GC线程同时工作,有效利用多核计算的能力。
    b)并发性:拥有与应用程序交替执行的能力,部分工作可以和应用程序同时执行。一般来说,不会在整个回收期间完全阻塞应用。
    c)分代收集:对比其他的收集器,它可以同时兼顾新生代和老年代。
    d)空间整理:G1每次回收都会有效的复制对象,减少空间碎片。
    e)可预见性:因为分区的原因,G1可以选择部分区域进行内存回收,减小了回收范围,对全局停顿也能得到较好的控制。G1 GC 有计划地避免在整个 Java 堆中进行全区域的垃圾收集。G1 跟踪各个 Region 里面的垃圾堆积的价值大小(回收所获得的空间大小以及回收所需时间的经验值),在后台维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的 Region。

侧重点在于回收垃圾最大量的区间(Region),所以我们给 G1 一个名字:垃圾优先(Garbage First)。

————————————————
版权声明:本文为CSDN博主「StriveFarrell」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/someby/article/details/83691807

G1并不会等内存耗尽(串行、并行)或者快耗尽(CMS)的时候开始垃圾收集,而是在内部采用了启发式算法,在老年代找出具有高收集收益的分区进行收集。
可预测的停顿:G1除了追求低停顿外,还能建立可以预测停顿时间的模型。能让使用者明确指定在一个长度为M毫秒的时间段,消耗在垃圾回收上的时间不超过N毫秒。可以根据用户设置的暂停时间目标自动调整年轻代和总堆大小,暂停目标越短年轻代空间越小、总空间就越大;

作者:蜜糖的代码注释
链接:https://www.jianshu.com/p/530b33be2373
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。





相较于 CMS,G1 还不具备全方位、压倒性优势。比如在用户程序运行过程中,G1 无论是为了垃圾收集产生的内存占用(Footprint)还是程序运行时的额外执行负载(Overload)都要比 CMS 要高。
从经验上来说,在小内存应用上 CMS 的表现大概率会优于 G1,而 G1 在大内存应用上则发挥其优势。平衡点在 6-8GB 之间。

著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。
作者:Nemo
链接:https://www.cnblogs.com/blknemo/p/13329369.html
来源:博客园

G1中的 RSet 可能会占据整个堆容量的 20%乃至更多,其SNAP机制也会产生更多的浮动垃圾,在占用的内存需求上更大,不推荐在堆空间比较小,尤其小于 6G 的情况下使用 G1。此外,G1停顿时间的瓶颈主要是标记-复制中转移阶段的STW,主要是因为G1未能解决转移过程中准确定位对象地址的问题。

注意:G1虽然有concurrent global marking,但该项是可选的,在G1中的垃圾回收的瓶颈在于copying算法的效率。

https://blog.csdn.net/tofucai/article/details/107624085

posted @ 2022-04-22 15:06  TomStudio  阅读(0)  评论(0)    收藏  举报