命令行选项和最佳实践
在这个章节,让我们一起看看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 |
除非注明,赵岩的博客文章均为原创,转载请以链接形式标明本文地址
本文地址:https://zhaoyanblog.com/archives/440.html