JVM-垃圾收集器

   

Parallel Scavenge:吞吐量优先收集器

吞吐量:CPU用于运行用户代码的时间与CPU总消耗时间的比值,(吞吐量Throughput = 运行用户代码时间/(运行用户代码时间+垃圾收集时间) or 吞吐量=(JVM运行时间-GC时间)/JVM运行时间)

停顿时间:

吞吐量:适合后台运算而不需要太多交互的任务;

Parallel Scavenge+Parallel Old:在注重吞吐量以及CPU资源敏感的场景,可优先考虑

CMS:低停顿收集器

CMS 默认启动的回收线程数是(CPU数+3)/4,即CPU在4个以上时,并发回收时GC线程>=25%的CPU资源,且随着CPU数的增加而下降。

CPU数1->GC数:(1+3)/4=1

CPU数2->GC数:(2+3)/4=1.25【?】

CPU数4->GC数:(4+3)/4=1.75【?】

CPU数8->GC数:(8+3)/4=2.75【?】

CPU数16->GC数:(16+3)/4=4.75【?】

CPU数32->GC数:(32+3)/4=8.75【?】

CPU数64->GC数:(64+3)/4=16.75【?】

CMS中的“浮动垃圾”【Floating Garbage】:并发清理阶段用户线程还在运行,这段时间就可能产生新的垃圾,新的垃圾在此次GC无法清除,只能等到下次清理。这些垃圾叫浮动垃圾。

   Serial ParNew Parallel Scavenge Serial Old Parallel Old CMS G1收集器
简介    

吞吐量优先收集器

自适应调节方式

是Serial的老年代版本 是Parallel Scavenge的老年代版本

低停顿收集器

Mark Sweep即标记-清除算法

 
关注点    

达到一个可控的吞吐量

    最短回收停顿时间  
优点  简单而高效(与其他收集器的单线程比)          并发收集、低停顿

低停顿,停顿时间可控

缺点          

1.对CPU资源非常敏感,默认启动的回收线程数是(CPU数+3)/4,即CPU在4个以上时,并发回收时GC线程>=25%的CPU资源,且随着CPU数的增加而下降。

2.CMS无法处理浮动垃圾(Floating Garbage),可能出现“Concurrent Mode Failure”失败而导致另一次Full GC产生。

-XX:CMSInitiatingOccupancyFraction的值来设定触发百分比

JDK1.5:默认68%,若应用中老年代增长不是太快,可以适当调高;

JDK1.6:默认92%

若CMS运行期间预留的内存无法满足程序需要,就会出现“Concurrent Mode Failure”失败,此时启动后备预案,临时使用Serial Old,此时停顿超长,因此不能设置太高,容易导致大量Concurrent Mode Failure失败,性能反而降低;

3.标记-清除,会有大量空间碎片产生。空间碎片过多时,会给大对象分配带来麻烦,往往会出现老年代还有很大空间剩余,但无法找到足够大的连续空间来分配当前对象,不得不提前触发1次FGC。

-XX:+UseCMSCompactAtFullCollection 默认为0,设置执行多少次不压缩的FGC后,来一次带压缩的。

 
产生版本         JDK1.6 JDK1.5  JDK1.7
收集范围  新生代  新生代  新生代      

整个Java堆划分成大小相等的独立区域(Region)

新生代:部分Region的集合(不需要连续)

老年代:部分Region的集合(不需要连续)

收集方案

新生代:复制算法

新生代:复制算法

除了使用多线程,其他大多和Serial完全一样

 新生代:复制算法      

优先列表:优先回收价值最大的Region

优先列表内容:维护各个Region回收所获得的空间大小及回收所需时间的经验值

适合领域 Client模式下的虚拟机(如:桌面应用场景)  Server下首选(重要因为只有ParNew可以与CMS配合工作)  

主要意义:Client模式下的虚拟机

server模式下:

1.JDK1.5及以前版本中与Parallel Scavenge搭配;

2.作为
CMS的后备预案,在CMS发生Concurrent Mode Failure时使用;

    服务端应用
使命             替换掉JDK1.5中的CMS
是否多线程

单线程

只用1个CPU、1条GC线程去完成GC工作,

且需暂停其他所有工作线程,直到GC结束

多线程

多条GC线程去完成GC工作,

且需暂停其他所有工作线程,直到GC结束

        多线程

并行(Parallel)

多条GC线程并行工作,但用户线程需等待

并行 并行  并行       与Java线程并行

并发(Concurrent)

用户线程与GC线程同时执行,在不同的CPU上

            使用多CPU来缩短Stop The World停顿时间
分代收集             是【可独立管理整个堆】
空间整合             整体基于“标记-整理”算法,局部(两个Region间)基于“复制”算法,
是否会产生空间碎片             不会产生空间碎片,有利于程序长时间运行
可预测的停顿           降低停顿

降低停顿,建立可预测的停顿时间模型(在M毫秒内,消耗在垃圾收集上的时间不得超过N毫秒)

原因:有计划的避免在整个Java堆中进行全区域的GC

 维护Remembered Set             对引用类型数据写时,会中断一下,检查其引用的对象是否处于不同的Region中,若是,便通过CardTable记录到R Set中
 不对全堆扫描处理             在GC根节点的枚举范围中加入Remembered Set即可
 1初始标记  
 
 
   

 【停顿】仅仅标记GC Roots能直接关联到的对象

【停顿】【耗时短】

标记GC Roots能直接关联到的对象

修改TAMS,让之后能在正确可用的Region中创建新对象

 2并发标记            【并发】进行GC Roots Tracing

【耗时长】 【与用户程序并行执行】

从GC Root开始,对堆中对象进行可达性分析,找出存活对象

 3最终标记          

 【停顿】

重新标记

修正并发标记期间用户程序导致标记变动的那部分对象的标记记录

比阶段1长,但远比阶段2短

【停顿】【GC多线程并行执行】

目的:修正在并发标记期间用户程序运行导致标记产生变动的那一部分标记记录,

这段时间的对象变化记录在现场Remembered Set Logs里,

把Remembered Set Logs的数据合并到Remembered Set,

4并发清除              
 参数  

-XX:+UseConcMarkSweepGC 选项后默认使用ParNew

-XX:+UseParNewGC 强制使用ParNew

-XX:ParallelGCThreads 设定垃圾收集的线程数(必须:建议值等于容器核数)

 -XX:MaxGCPauseMillis 控制最大的GC停顿时间

-XX:GCTimeRatio 直接设置吞吐量

(GCTimeRatio默认99,即允许最大垃圾收集时间=1/(1+99)=1%)

GC自适应调节策略GC Ergonomics:(需要设定最大堆-Xmx 、最大停顿或吞吐量)

-XX:+UseAdaptiveSizePolicy 开关参数,打开后不需要手工指定-Xmn、-XX:SurvivorRatio、-XX:PretenureSizeThreshold等细节参数,

     

-XX:CMSInitiatingOccupancyFraction的值来设定触发百分比

JDK1.5:默认68%,若应用中老年代增长不是太快,可以适当调高;

JDK1.6:默认92%;

-XX:+UseCMSCompactAtFullCollection 默认为0,设置执行多少次不压缩的FGC后,来一次带压缩的。

 -XX:+UseG1GC

-Xmx32g

-XX:MaxGCPauseMillis=200

-XX:ParallelGCThreads=n

设置 STW 工作线程数的值。设为服务虚拟内核数,n 的值与逻辑处理器的数量相同,最多为 8,如果逻辑处理器不止八个,则将 n 的值设置为逻辑处理器数的 5/8 左右。这适用于大多数情况,除非是较大的 SPARC 系统,其中 n 的值可以是逻辑处理器数的 5/16 左右。

-XX:ConcGCThreads=n

设置并行标记的线程数。将 n 设置为并行垃圾回收线程数 (ParallelGCThreads) 的 1/4 左右。

               
               
               
               
原文地址:https://www.cnblogs.com/WangXiaoYu-/p/10602670.html