欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

堆内存常见的分配策略、 经典的垃圾收集器、CMS与G1收集器及二者的比较,

来源: javaer 分享于  点击 2483 次 点评:241

堆内存常见的分配策略、 经典的垃圾收集器、CMS与G1收集器及二者的比较,


堆内存常见的分配策略

针对的是Serial 加 Serial Old 客户端默认收集器组合下的内存分配和回收策略

 

 

 经典的垃圾收集器

CMS 收集器

CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的垃圾收集器。从名字可以看出,CMS 是基于标记-清除算法的。它的运作过程主要分为四个步骤:

CMS 的缺点:

  • CMS收集器对处理器资源敏感。在并发阶段,虽然不会导致用户停顿(STW),但会占用一部分线程(计算机资源)导致应用程序变慢,吞吐量降低。CMS默认开启回收线程数是 (处理器核心数量 + 3)/4。当处理器核心数量大于4个时,垃圾回收线程只占不超过 25%的处理器资源,且随着处理器核心数量增加而降低。但处理器核心数量不足4个时,会严重影响用户程序。为了缓解这个问题,虚拟机提供了增量式并发收集器的CMS变种,在并发标记和并发清理过程中,垃圾收集线程和用户线程交替运行,但效果一般,已标记为废弃。
  • 无法处理“浮动垃圾”,有可能出现 Concurrent Mode Failure失败,导致进一步 STW 的Full GC在并发标记和并发清理过程中,用户线程还在运行,自然还会伴随新的垃圾对象的产生,但该部分的垃圾对象出现在标记过程结束以后,CMS无法在当次收集过程中处理他们(只能下次垃圾收集时处理),因此称为浮动垃圾。因此,CMS必须预留足够的内存空间提供给用户线程使用,JDK6,默认启动阈值为 92%(该值需要根据生产环境变化,太高,有可能频繁并发失败):要是CMS运行期间预留的内存无法满足程序分配新对象,触发并发失败(Concurrent Mode Failure),这时候JVM启动预备方案:冻结用户线程,临时启动 Serial Old 来进行老年代的手机,这样停顿时间会很长
  • 大量空间碎片。空间碎片过多会导致大对象分配失败(老年代还有很多空间,但没有连续的大空间),而不得不提前触发 Full GC。CMS提供了参数 -XX:+UseCMS-CompactAtFullCollection 开关参数(默认开启,JDK9之后废弃),用于在CMS不得不Full GC时开启碎片的合并整理过程。但整理涉及到移动对象,STW,停顿时间会变长。

 Garbage First (G1收集器)

目标是在延迟可控的范围内获取尽可能高的吞吐量

G1是面向堆内任何部分来组成回收集进行回收,衡量标准不再是它属于哪个分代,而是哪块内存中存放的垃圾最多,回收收益最大,这就是 G1 收集器的 Mixed GC 模式。 

G1不再坚持分代划分,而是把连续的Java 堆划分为多个大小相等的独立区域(Region),每个 Region 根据需要版本新生代的Eden、Survivor或老年代。收集器能够对扮演不同角色的Region采用不同的策略去处理。这样无论是新对象还是已经存活了一段时间的对象、熬过多次收集的就对象都能获得很好的收集效果。

Region 中还有一类特殊的 Humonggous 区域,专门用来存放大对象此处大对象,指的是内存大小超过一个 Region 容量一半的对象。每个Region的大小可以通过 -XX:G1HeapRegionSize 设定,取值范围为 1~32MB,且为2的N次幂。如果对象大小超过Region大小,将会被放到N个连续的 Humongous Region,G1的大多数行为将Humongous 作为老年代的一部分处理。

虽然 G1 仍然保留了新生代和老年代的概念,但新生代和老年代不再是固定的,他们都是一系列区域(不需要连续)的动态集合。G1 之所以能够建立可预测的停顿时间模型,是因为他将Region 作为可回收的最小单元。更具体的操作是:让G1 去跟踪各个Region 里面的垃圾堆积的“价值”大小,价值即回收所获得的空间大小以及回收所需要的经验值,然后在后台维护一个优先级列表,每次根据用户设定的允许的收集停顿时间(-XX:MaxGCPauseMills,默认200ms)优先处理回收价值最大的Region。这也是 “Garbage First“ 的由来。该方式保证了G1在有限的事件内获取尽可能高的收集效率。

 

G1收集器大致可以分为以下四个步骤:

只有并发标记可以与用户线程并发进行。

CMS 与 G1 比较

G1 的优点

G1 的缺点:

CMS 更适合在小内存应用上,而G1在大内存应用上能发挥更多优势。两者的内存临界点为 6 GB 到 8GB。

 

相关文章

    暂无相关文章
相关栏目:

用户点评