[翻译]G1垃圾收集器(六) 之 命令行选项和最佳实践

命令行选项和最佳实践

在这个章节,让我们一起看看G1的每个命令行选项。

基本的命令行选项

启用G1 GC,使用选项:-XX:+UseG1GC

这是一个最简单的命令行,来启动下载的JDK自带的demos和例子中的Java2Demo

java -Xmx50m -Xms50m -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -jar c:\javademos\demo\jfc\Java2D\Java2demo.jar

关键的命令行开关

-XX:+UseG1GC – 告诉JVM,使用G1 GC

-XX:MaxGCPauseMillis=200 – 设置一个目标最大暂停时间. 这是一个理想化的目标,JVM会尽可能的完成它. 因此,这个目标不一定能达到。默认是200ms。.

-XX:InitiatingHeapOccupancyPercent=45 – 整个堆栈使用达到百分之多少的时候,启动GC周期. 基于整个堆,不仅仅是其中的某个代的占用情况,G1根据这个值来判断是否要触发GC周期, 0表示一直都在GC,默认值是45(即45%慢了,或者说占用了)

最佳实践

在使用G1的时候,下面几个最佳实践你需要遵循

不要设置年轻代大小

显式的使用-Xmn设置年轻代的大小,会干预G1的默认行为。

  • G1就不会再考虑设定的暂停时间目标,所以本质上说,设定了年轻代大小就相当于禁用了目标暂停时间
  • G1就无法根据需要增大或者缩小年轻代的小心。既然大小固定了,就无法在大小上做任何改变了。

响应时间指标

不要根据平均响应时间(ART)作为衡量标准去设定XX:MaxGCPauseMillis=<N>选项,而是设定一个想在90%或者以上的时间都会满足这目标的值。也就是说90%的用户,都会在目标时间,甚至更短的时间内得到响应。记住设定的目标时间只是一个目标,不能保证永久都会满足这个目标。

什么是释放(撤销?)失败?

一个JVM当在回收存活或者晋升对象的时候,栈区域溢出了就会发生失败,因为堆的使用已经到达了最大值,不能再扩展。使用-XX:+PrintGCDetails选项,你会看到to-space overflow的日志。这个过程代价很高的。

  • GC还必须继续对内存进行释放
  • 拷贝不成功的对象继续留在原来的区域
  • 对CSets中对区域的RSets任何更新都要重新生成
  • 所有这些过程代价都是很高的

怎么避免释放(撤销?)失败?

为了避免放失败,考虑使用下面的选项:

  • 增大堆(内存)大小
    • 增大-XX:G1ReservePercent=n,默认是10
    • G1会预留一部分内存,制造一个假天花板,防止to-space的方式。
  • 早点启动标记周期
  • 增大并行标记的线程数,使用-XX:ConcGCThreads=n选项

G1 GC的开关选项完全列表

下面是G1 GC的所有的开关选项的列表,记得通过上面提到的最佳实践:

选项和默认值 描述
-XX:+UseG1GC 使用G1 GC
-XX:MaxGCPauseMillis=n 设置一个暂停时间期望目标,这是一个软目标,JVM会近可能的保证这个目标
-XX:InitiatingHeapOccupancyPercent=n 内存占用达到整个堆百分之多少的时候开启一个GC周期,G1 GC会根据整个栈的占用,而不是某个代的占用情况去触发一个并发GC周期,0表示一直在GC,默认值是45
-XX:NewRatio=n 年轻代和老年代大小的比例,默认是2
-XX:SurvivorRatio=n eden和survivor区域空间大小的比例,默认是8
-XX:MaxTenuringThreshold=n 晋升的阈值,默认是15(译者注:一个存活对象经历多少次GC周期之后晋升到老年代)
-XX:ParallelGCThreads=n GC在并行处理阶段试验多少个线程,默认值和平台有关。(译者注:和程序一起跑的时候,使用多少个线程)
-XX:ConcGCThreads=n 并发收集的时候使用多少个线程,默认值和平台有关。(译者注:stop-the-world的时候,并发处理的时候使用多少个线程)
-XX:G1ReservePercent=n 预留多少内存,防止晋升失败的情况,默认值是10
-XX:G1HeapRegionSize=n G1 GC的堆内存会分割成均匀大小的区域,这个值设置每个划分区域的大小,这个值的默认值是根据堆的大小决定的。最小值是1Mb,最大值是32Mb

留言

提示:你的email不会被公布,欢迎留言^_^

*

验证码 *