Jvm 参数
JVM参数 - # 001 ReservedCodeCacheSize
参数:-XX:ReservedCodeCacheSize
-
含义:
Reserved code cache size (in bytes) - maximum code cache size
用于设置Code Cache大小,JIT编译的代码都放在Code Cache中,若Code Cache空间不足则JIT无法继续编译,并且会去优化,比如编译执行改为解释执行,由此,性能会降低 -
默认值
| os/jdk | jdk6 | jdk7 | jdk8 |
| ----- | -----| ----- | ----- |
| linux | 50331648 | 50331648 | 251658240 |
| maxos | 50331648 | 50331648 | 251658240 | -
等价参数:
-Xmaxjitcodesize -
举例:codeCache调优
以client模式或者是分层编译模式运行的应用,由于需要编译的类更多(C1编译器编译阈值低,更容易达到编译标准),所以更容易耗尽codeCache。当发现codeCache有不够用的迹象(通过上一节提到的监控方式)时,可以通过启动参数来调整codeCache的大小。
jdk8中,提供了一个启动参数XX:+PrintCodeCache在jvm停止的时候打印出codeCache的使用情况。其中max_used就是在整个运行过程中codeCache的最大使用量。
-XX:ReservedCodeCacheSize=256M
JVM参数 - 002 StringTableSize
参数:-XX:StringTableSize
-
含义:
Number of buckets in the interned String table
String.intern()被调用时会往Hashtable插入一个String(若该String不存在),这里的Table就是StringTable,此参数就是这个StringTable的大小
若此参数设置过小,明显的问题就是过多的hash碰撞,造成在查找字符串时比较消耗CPU资源
JDK1.6起,当冲突次数超过100次会自动rehash,即便如此,若此参数设置过小会导致不断的rehash,依然会过度消耗CPU资源
建议将此参数设置的值稍大一些,以减少hash冲突 -
默认值
| os/jdk | jdk6 | jdk7 | jdk8 |
| ----- | -----| ----- | ----- |
| linux | 1009 | 60013 | 60013 |
| maxos | 1009 | 60013 | 60013 | -
举例
-XX:StringTableSize=60013
JVM参数 - 003 CompileCommand
参数:-XX:CompileCommand
- 含义:
*Specifies a command to perform on a method. **
该参数用于定制编译需求,比如过滤某个方法不做JIT编译
若未指定方法描述符,则对全部同名方法执行命令操作,具体如何指定见下文[举例]
可使用星号通配符()指定类或方法,具体如何使用见下文[举例]
该参数可多次指定,或使用 换行符(\n)分隔参数后的多个命令
解析完该命令后,JIT编译器会读取.hotspot_compiler文件中的命令,该参数也可写在.hotspot_compiler文件中
可使用-XX:CompileCommandFile指定.hotspot_compiler文件为其他文件
用法:
-XX:CompileCommand=command,method[,option]
-
命令:
exclude,跳过编译指定的方法
compileonly,只编译指定的方法
inline/dontinline,设置是否内联指定方法
print,打印生成的汇编代码
break,JVM以debug模式运行时,在方法编译开始处设置断点
quiet,不打印在此命令之后、通过-XX:CompileCommand指定的编译选项
log,记录指定方法的编译日志,若未指定,则记录所有方法的编译日志
其他命令,option,help -
举例:
- 设置编译器跳过编译com.test.Dummy类test方法的4种写法
-XX:CompileCommand=exclude,com/test/Dummy.test
-XX:CompileCommand=exclude,com/test/Dummy::test
-XX:CompileCommand=exclude,com.test.Dummy::test
-XX:CompileCommand="exclude com/test/Dummy test" - 设置编译器只跳过编译java.lang.String类int indexOf(String)方法
-XX:CompileCommand="exclude,java/lang/String.indexOf,(Ljava/lang/String;)I" - 设置编译器跳过编译所有类的indexOf方法
-XX:CompileCommand=exclude,*.indexOf
JVM参数 - 004 MaxTenuringThreshold
参数:-XX:MaxTenuringThreshold
-
含义:
Sets the maximum tenuring threshold for use in adaptive GC sizing.
The largest value is 15.
The default value is 15 for the parallel (throughput) collector, and 6 for the CMS collector.
在可自动调整对象晋升老年代年龄阈值的GC中,该参数用于设置上述年龄阈值的最大值
参数值最大为15
Parallel Scavenge中默认值为15,CMS中默认值为6,G1中默认值为15 -
默认值:
os/jdk | jdk6 | jdk7 | jdk8 |
---|---|---|---|
linux | 15 | 15 | 15 |
maxos | 4 | 15 | 15 |
JVM参数 - 005 CMSScavengeBeforeRemark
参数:-XX:CMSScavengeBeforeRemark
-
含义:
Enable scavenging attempts before the CMS remark step.
开启或关闭在CMS重新标记阶段之前的清除(YGC)尝试
CMS并发标记阶段与用户线程并发进行,此阶段会产生已经被标记了的对象又发生变化的情况,若打开此开关,可在一定程度上降低CMS重新标记阶段对上述“又发生变化”对象的扫描时间,当然,“清除尝试”也会消耗一些时间
注,开启此开关并不会保证在标记阶段前一定会进行清除操作 -
默认值:
os/jdk | jdk6 | jdk7 | jdk8 |
---|---|---|---|
linux | false | false | false |
maxos | false | false | false |
- 举例说明
在CMS GC前启动一次ygc,目的在于减少old gen对ygc gen的引用,降低remark时的开销-----一般CMS的GC耗时 80%都在remark阶段
JVM参数 - 006 ExplicitGCInvokesConcurrent
参数:-XX:ExplicitGCInvokesConcurrent
-
含义:
Enables invoking of concurrent GC by using the System.gc() request.
This option is disabled by default and can be enabled only together with the -XX:+UseConcMarkSweepGC option.
System.gc()是正常FULL GC,会STW
打开此参数后,在做System.gc()时会做background模式CMS GC,即并行FULL GC,可提高FULL GC效率
注,该参数在允许systemGC且使用CMS GC时有效
更多详细内容阅读(强烈推荐)JVM源码分析之SystemGC完全解读 -
默认值:
os/jdk | jdk6 | jdk7 | jdk8 |
---|---|---|---|
linux | false | false | false |
maxos | false | false | false |
007 UseGCLogFileRotation || NumberOfGCLogFiles || GCLogFileSize
-
参数:
-XX:UseGCLogFileRotation
-XX:NumberOfGCLogFiles
-XX:GCLogFileSize -
含义:
这次分享了3个设置滚动记录GC日志的参数
通过参数-Xloggc:xxx可指定GC日志文件路径
普通情况下,GC日志文件内容会不断积累,进程重启后日志文件会被覆盖
这次分享的3个参数在设置-Xloggc参数的前提下有效 -
-XX:UseGCLogFileRotation
Enabled GC log rotation, requires -Xloggc.
打开或关闭GC日志滚动记录功能,要求必须设置 -Xloggc参数 -
-XX:NumberOfGCLogFiles
Set the number of files to use when rotating logs, must be >= 1.
The rotated log files will use the following naming scheme, <filename>.0, <filename>.1, ..., <filename>.n-1.
设置滚动日志文件的个数,必须大于1
日志文件命名策略是,<filename>.0, <filename>.1, ..., <filename>.n-1,其中n是该参数的值 -
-XX:GCLogFileSize
The size of the log file at which point the log will be rotated, must be >= 8K.
设置滚动日志文件的大小,必须大于8k
当前写日志文件大小超过该参数值时,日志将写入下一个文件
注,GC日志最好不滚动输出,因为之前的关键日志可能会被冲掉,日志写入同一个文件更方便分析
默认值:
-XX:UseGCLogFileRotation
os/jdk | jdk6 | jdk7 | jdk8 |
---|---|---|---|
linux | false | false | false |
maxos | false | false | false |
-XX:NumberOfGCLogFiles
os/jdk | jdk6 | jdk7 | jdk8 |
---|---|---|---|
linux | 0 | 0 | 0 |
maxos | 0 | 0 | 0 |
-XX:GCLogFileSize
os/jdk | jdk6 | jdk7 | jdk8 |
---|---|---|---|
linux | 8192 | 8192 | 8192 |
maxos | 0 | 8192 | 8192 |
- 举例:
打开GC日志滚动记录功能
-XX:+UseGCLogFileRotation
设置滚动日志文件个数为10
-XX:NumberOfGCLogFiles=10
设置滚动日志文件大小为512k
-XX:GCLogFileSize=512k
相关参数:
-Xloggc:xxx 指定GC日志文件路径,设置改参数后分享的3个参数有效
GC日志其实也支持滚动输出的
-Xss:每个线程的栈大小
-Xms:初始堆大小,默认物理内存的1/64
-Xmx:最大堆大小,默认物理内存的1/4
-Xmn:新生代大小
-XX:NewSize:设置新生代初始大小
-XX:NewRatio:默认2表示新生代占年老代的1/2,占整个堆内存的1/3。
-XX:SurvivorRatio:默认8表示一个survivor区占用1/8的Eden内存,即1/10的新生代内存。
-XX:MetaspaceSize:设置元空间大小
-XX:MaxMetaspaceSize:设置元空间最大允许大小,默认不受限制,JVM Metaspace会进行动态扩展。
垃圾回收统计信息
-XX:+PrintGC
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-Xloggc:filename
收集器设置
-XX:+UseSerialGC:设置串行收集器
-XX:+UseParallelGC:设置并行收集器
-XX:+UseParallelOldGC:老年代使用并行回收收集器
-XX:+UseParNewGC:在新生代使用并行收集器
-XX:+UseParalledlOldGC:设置并行老年代收集器
-XX:+UseConcMarkSweepGC:设置CMS并发收集器
-XX:+UseG1GC:设置G1收集器
-XX:ParallelGCThreads:设置用于垃圾回收的线程数
并行收集器设置
-XX:ParallelGCThreads:设置并行收集器收集时使用的CPU数。并行收集线程数。
-XX:MaxGCPauseMillis:设置并行收集最大暂停时间
-XX:GCTimeRatio:设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+n)
CMS收集器设置
-XX:+UseConcMarkSweepGC:设置CMS并发收集器
-XX:+CMSIncrementalMode:设置为增量模式。适用于单CPU情况。
-XX:ParallelGCThreads:设置并发收集器新生代收集方式为并行收集时,使用的CPU数。并行收集线程数。
-XX:CMSFullGCsBeforeCompaction:设定进行多少次CMS垃圾回收后,进行一次内存压缩
-XX:+CMSClassUnloadingEnabled:允许对类元数据进行回收
-XX:UseCMSInitiatingOccupancyOnly:表示只在到达阀值的时候,才进行CMS回收
-XX:+CMSIncrementalMode:设置为增量模式。适用于单CPU情况
-XX:ParallelCMSThreads:设定CMS的线程数量
-XX:CMSInitiatingOccupancyFraction:设置CMS收集器在老年代空间被使用多少后触发
-XX:+UseCMSCompactAtFullCollection:设置CMS收集器在完成垃圾收集后是否要进行一次内存碎片的整理
G1收集器设置
-XX:+UseG1GC:使用G1收集器
-XX:ParallelGCThreads:指定GC工作的线程数量
-XX:G1HeapRegionSize:指定分区大小(1MB~32MB,且必须是2的幂),默认将整堆划分为2048个分区
-XX:GCTimeRatio:吞吐量大小,0-100的整数(默认9),值为n则系统将花费不超过1/(1+n)的时间用于垃圾收集
-XX:MaxGCPauseMillis:目标暂停时间(默认200ms)
-XX:G1NewSizePercent:新生代内存初始空间(默认整堆5%)
-XX:G1MaxNewSizePercent:新生代内存最大空间
-XX:TargetSurvivorRatio:Survivor填充容量(默认50%)
-XX:MaxTenuringThreshold:最大任期阈值(默认15)
-XX:InitiatingHeapOccupancyPercen:老年代占用空间超过整堆比IHOP阈值(默认45%),超过则执行混合收集
-XX:G1HeapWastePercent:堆废物百分比(默认5%)
-XX:G1MixedGCCountTarget:参数混合周期的最大总次数(默认8)
JVM调优参数参考
1.针对JVM堆的设置,一般可以通过-Xms -Xmx限定其最小、最大值,为了防止垃圾收集器在最小、最大之间收缩堆而产生额外的时间,通常把最大、最小设置为相同的值;
2.年轻代和年老代将根据默认的比例(1:2)分配堆内存, 可以通过调整二者之间的比率NewRadio来调整二者之间的大小,也可以针对回收代。
比如年轻代,通过 -XX:newSize -XX:MaxNewSize来设置其绝对大小。同样,为了防止年轻代的堆收缩,我们通常会把-XX:newSize -XX:MaxNewSize设置为同样大小。
3.年轻代和年老代设置多大才算合理
1)更大的年轻代必然导致更小的年老代,大的年轻代会延长普通GC的周期,但会增加每次GC的时间;小的年老代会导致更频繁的Full GC
2)更小的年轻代必然导致更大年老代,小的年轻代会导致普通GC很频繁,但每次的GC时间会更短;大的年老代会减少Full GC的频率
如何选择应该依赖应用程序对象生命周期的分布情况: 如果应用存在大量的临时对象,应该选择更大的年轻代;如果存在相对较多的持久对象,年老代应该适当增大。但很多应用都没有这样明显的特性。
在抉择时应该根 据以下两点:
(1)本着Full GC尽量少的原则,让年老代尽量缓存常用对象,JVM的默认比例1:2也是这个道理 。
(2)通过观察应用一段时间,看其他在峰值时年老代会占多少内存,在不影响Full GC的前提下,根据实际情况加大年轻代,比如可以把比例控制在1:1。但应该给年老代至少预留1/3的增长空间。
4.在配置较好的机器上(比如多核、大内存),可以为年老代选择并行收集算法: -XX:+UseParallelOldGC 。
5.线程堆栈的设置:每个线程默认会开启1M的堆栈,用于存放栈帧、调用参数、局部变量等,对大多数应用而言这个默认值太了,一般256K就足用。
理论上,在内存不变的情况下,减少每个线程的堆栈,可以产生更多的线程,但这实际上还受限于操作系统。
网友评论