jvm---3、GC收集分类及配置参数

Serial   
是一个单线程收集器,单线程是指进行GC时,必须要暂停所有的工作线程,直到GC 结束。
优点:
1、简单高效(对于其它GC收集器单线程相比),
2、适用于单个CPU 的环境,不会有线程交互的开销。一般Client 模式下的虚拟机使用的是这个GC收集器。
缺点:Stop the world

新生代采用“复制算法”,老年代采用“标记--整理算法”

控制参数:

ParNew
就是Serial 的多线程版本。新生代回收的时候是多线程,老年代回收还是单线程的。
优点:
1、除了Serial 之外只有它能和CMS 配合使用
2、
缺点:Stop the world

新生代采用“复制算法”,老年代采用“标记--整理算法”

控制参数:
-XX:+UseConcMarkSweepGC 使用这个选项后默认的GC
-XX:+UseParNewGC   强制使用GC

Parallel Scavenge
是一个新生代收集器,采用“复制算法”,是并行多线程收集器。
特点: 关注的是达到一个可控制的吞吐量(Throughput),即CPU 用于运行用户代码时间与CPU总消耗时间比值。吞吐量=运行代码时间/(运行代码时间+GC时间)。所以适合做后台计算任务,不适合太多交互。

控制参数:
-XX:MaxGCPauseMillis    最大垃圾收集停顿时间。设置大于0的毫秒数,收集器保证GC回收不超过这个时间。并不是越小越好,值越小可能回收的频率越高。
-XX:GCTimeRatio         直接设置吞吐量大小。大于0小于100的整数,默认是99
-XX:+UseAdaptiveSizePoblicy  是一个开关参数,打开后就不需要设置-Xmn, Eden,Survivor 比例,晋升老年代对象大小等参数了。JVM 会监控并自动调整这些参数,保证吞吐量。

Serial Old
是 Serial 的老年代收集器,使用“标记--整理”算法。
主要用途:
1、在Client 模式下的虚拟机使用。
2、CMS 收集器的后备,在并发收集器发生Concurrent Mode Failure 时使用
3、jdk.15之前与Parallel Scavenge 配合使用


Parallel Old
是 Parallel Scavenge 的老年代版本,使用多线程“标记--整理”算法。
主要用途:在注重吞吐量及CPU资源敏感的场合,都可以使用Parallel Scavenge 和 Parallel Old 收集器。

CMS
Concurrent Mark Sweep  是一种获取最短回收停顿时间为目标的收集器。
重视服务器的响应速度,希望停顿时间短。 GMS 符合这样的应用需求。
回收过程:
1、初始标记 需要“Stop The World”,仅仅只标记一下GC Roots 能直接关联的到的对象,速度很快。
2、并发标记 就是进行GC Roots Tracing 的过程
3、重新标记 需要“Stop The World”,修正并发标记期间因用户程序继续动作而导致标记产生变动的那一部分对象的标记记录。停顿的时间比并发标记短。
4、并发消除
并发标记、并发消除会和用户的线程一起工作。
优点:并发收集,低停顿
缺点:
1、对CPU 资源敏感。GMS 默认启动回收线程数=(cpu数+3)/4,可以通过 ParallelCMSThreads 设置。在并发阶段不会导致用户线程停顿,但是会占用一部分CPU 资源,所有应用变慢了,总体吞吐量低了。
2、无法回收“浮动垃圾”。
“浮动垃圾”:回收线程和用户线程并行的,在回收过程中,又产生了新的垃圾,这部分内存是只能等待下一次GC 回收,这部分的垃圾就是“浮动垃圾”。
回收过程中,用户线程还在运行,那么就要保证足够的内存给用户线程。所有不能等到老年代几乎被用完了才进行回收。jdk1.6默认设置是92,老年代被占用了92%,就进行GC。要是GC 期间内存无法满足程序需要,就会产生“Concurent Mode Failure” 这时就启动后备预案:Serial Old 进行GC。所以 CMSInitiatingOccupancyFraction 值如果设置的比较小,那么可以老年代就是 Serial Old GC 了。
3、采用的是“消除--标记”算法,所以会产生内存碎片。所以可能内存够用,但是分配大对象时就要触发Full GC 了。提供两个参数 UseCMSCompactAtFullConllection , CMSFullGCsBeforeCompaction 解决这个问题

控制参数:
-XX:CMSInitiatingOccupancyFraction  jdk1.6默认设置是92,老年代被占用了92%,就进行GC
-XX:UseCMSCompactAtFullConllection 开关参数(默认开启)用于CMS收集器进行Full GC 时开启内存碎片的合并整理过程。
-XX:CMSFullGCsBeforeCompaction    进行多少次不碎片整理的Full GC 进行一次带碎片整理的Full GC 。默认是0,每次Full GC 都进行碎片整理。
-XX:+UseConcMarkSweepGC  启用GMS
-XX:ParallelCMSThreads   设置GMS 启动回收线程数
-XX:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled  这两个是永久代回收的,不用管。
-XX:+CMSParallelRemarkEnabled   重新标记并行,默认开启
-XX:+CMSScavengeBeforeRemark    重新标记时先执行一次Minor GC ,默认关闭

G1
设计:
将GC堆分为多个大小相等的独立区域(Region,一个region 就是一块内存,可以存放多个对象),保留新生代、老年代的概念,但是已经没有了物理隔离了,新生代和老年代都是一部分不连续的Region集合。内存的回收就是对Region 的回收。
每个Region 都有一个Remembered Set,jvm 发程序在对Reference类型的数据进行写操作时,会产生一个Write Barrier 暂时中断写操作,检查Reference引用的对象是否处于不同的Region 之中(就像检查对象是否老年代引用了新生代中的对象),如果是通过 CardTable 把相关的引用信息记录到被引用对象所属的Region 和Remembered Set 中。当Region 回收时,在GC 根节点的枚举范围内加入Remembered Set ,就可以保证不全堆扫描Region了,也不会有遗漏。

特点:
1、并行与并发 充分利用cpu,缩短Stop The World
2、分代收集 可以不配合其它收集器,独自管理整个GC堆。采用不同的方式处理新的对象和已经存活了一段时间、经过几次GC 后存活的旧对象获取更好的收集效果
3、空间整合   不会产生内存碎片,因为都是Region
4、可预测的停顿 G1跟踪各个Region 进而垃圾堆积的价值大小,在后台维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的Region。所以G1可以在有效的时间内保证最高的收集效率。

过程(不考虑写Remembered Set):
1、初始标记 标记一下GC Roots 能直接关联到的对象,并修改TAMS(Next Top at Mark Start)的值,让下一阶段用线程并发时,可以在正确可用的Region中创建对象。会产生 Stop The World ,时间会很短。
2、并发标记 对象到 GC Roots 的可达性分析,找出存活对象。和用户线程并发执行。
3、最终标记 修正在并发标记期间因用户程序继续动作而导致标记生产变化的那一部分标记记录。jvm将这段时间(并发标记)对象变化记录在线程Remembered Set Logs 里面,最终标记把Remembered Set Logs 的数据合并到Remembered Set 中这个阶段要停顿线程,但是可以并行执行。
4、筛选回收 筛选对各个Region 的回收价值和成本进行排序,根据用户期望的GC 停顿时间来制定回收计划。这个阶段可以和用户线程并发执行,但是只回收一部分Region,时间是用户控制的,而且停顿用户线程可以大幅提高回收效率。

控制参数:
-XX:+UseG1GC 使用 G1 (Garbage First) 垃圾收集器
-XX:MaxGCPauseMillis=n 设置最大GC停顿时间(GC pause time)指标(target). 这是一个软性指标(soft goal), JVM 会尽量去达成这个目标.
-XX:InitiatingHeapOccupancyPercent=n 启动并发GC周期时的堆内存占用百分比. G1之类的垃圾收集器用它来触发并发GC周期,基于整个堆的使用率,而不只是某一代内存的使用比. 值为 0 则表示"一直执行GC循环". 默认值为 45.
-XX:ConcGCThreads=n 并发垃圾收集器使用的线程数量. 默认值随JVM运行的平台不同而不同.
-XX:G1ReservePercent=n 预留内存的百分比,防止晋升失败的情况,范围是0到50,默认值是10
-XX:G1HeapRegionSize=n 使用G1时Java堆会被分为大小统一的的区(region)。此参数可以指定每个Region的大小, 最小值为 1Mb, 最大值为 32Mb.


控制参数总结:
UseSerialGC jvm client 模式下,打开此开关后,使用Serial+Serial Old 组合收集器
UseParNewGC 打开此开关,使用 ParNew + Serial Old 组合收集器
UseConcMarkSweepGC 打开此开关使用 ParNew + CMS 组合收集器,当CMS 发生Concurrent Mode Failure 时使用Serial Old 作为备用收集器
UseParallelGC jvm Server 模式下,打开此开关,使用 Parallel Scavenge + Serial Old 组合收集器
UseParalledlOldGC 打开此开关使用 Parallel Scavenge + Parallel Old 组合收集器
SurvivorRatio 新生代 Eden:Survivor值,默认是8
PretenureSizeThreshold 直接晋升到老年代对象大小,设置后如果对象大小大于此值,那么对象直接分配到老年代
MaxTenuringThreshold 晋升到老年代的年龄。第一次Minor GC 之后,年龄加1,当超过这个值后晋升到老年代
UseAdaptiveSizePoblicy 动态调整java堆中各个区域的大小以及进入老年代的年龄
HandlePromotionFailure  是否允许担保失败
ParallelGCThreads 并行GC时,进行内存回收的线程数量
GCTimeRatio GC时间占总时间比率,默认99,即 1%的时间GC。仅在使用Parallel Scavenge 时有用。
MaxGCPauseMills  最大GC 停顿时间。仅在使用Parallel Scavenge 时有用。
CMSInitiatingOccupancyFraction  CMS收集器在老年代空间被使用多少后触发垃圾回收。默认是 68%,只有CMS 收集器时有用
UseCMSCompactAtFullConllection 开关参数(默认开启)用于CMS收集器进行Full GC 时开启内存碎片的合并整理过程。
CMSFullGCsBeforeCompaction    进行多少次不碎片整理的Full GC 进行一次带碎片整理的Full GC 。默认是0,每次Full GC 都进行碎片整理。

猜你喜欢

转载自blog.csdn.net/convict_eva/article/details/80585752