JVM 常见配置参数
JVM 配置常见参数Java虚拟机的参数,在启动jar包的时候通过java 命令指定JVM参数-options表示Java虚拟机的启动参数,class为带有main()函数的Java类,args表示传递给主函数main()的参数。
JVM 配置常见参数
Java虚拟机的参数,在启动jar包的时候通过java 命令指定JVM参数
-options表示Java虚拟机的启动参数,class为带有main()函数的Java类,args表示传递给主函数main()的参数。
一、系统查看参数:
-XX:+PrintVMOptions可以在程序运行时打印虚拟机接收到
-XX:+PrintCommandLineFlags可以打印传递给虚拟机的显式和隐式参数,打印出包括配置文件在内的配置
-XX:+PrintFlagsFinal,它会打印所有的系统参数的值
java -XX:+PrintCommandLineFlags -version
-XX:+PrintFlagsFinal,打印JVM所有参数的值
-XX:+PrintGC,打印GC信息
-XX:+PrintGCDetails,打印GC详细信息
-XX:+PrintGCTimeStamps,打印GC的时间戳
-Xloggc:filename,设置GC log文件的位置
-XX:+PrintHeapAtGC查看 GC 前后的堆、方法区可用容量变化
-XX:+PrintTenuringDistribution,查看熬过收集后剩余对象的年龄分布信息
-XX:+PrintGCApplicationConcurrentTime
-XX:+PrintGCApplicationStoppedTime 查看 GC 过程中用户线程并发时间以及停顿的时间
1.1.1 查看当前系统的垃圾回收器使用的是哪种
jinfo -flags [进程pid]
找到-useXXXX这样的参数,参数后即为所使用的GC回收器
[xxx@localhost vpdm]$ jinfo -flags 17049
Attaching to process ID 17049, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.341-b10
Non-default VM flags: -XX:CICompilerCount=4 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=null -XX:InitialHeapSize=805306368 -XX:MaxHeapSize=805306368 -XX:MaxNewSize=268435456 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=268435456 -XX:OldSize=536870912 -XX:+PrintFlagsFinal -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseParallelGC
Command line: -Xms768m -Xmx768m -XX:+PrintFlagsFinal -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./dumplog/dumplog.log
1.1 堆的配置参数
-Xms -Xmx 设置初始堆和最大堆内存
-Xmn 设置新生代内存大小
-XX:NewRatio 。可以设置老年代与新生代的比例。设置一个较大的新生代会减小老年代的大小,这个参数对系统性能及GC行为有很大的影响。新生代的大小一般设置为整个堆空间的1/3到1/4。默认值为设置老年代和新生代内存占比,默认值为2:1。
默认-XX:NewRatio=2新生代占1,老年代占2,年轻代占整个堆的1/3
假如
-XX:NewRatio=4新生代占1,老年代占4,年轻代占整个堆的1/5 NewRatio值就是设置老年代的占比,剩下的1给新生代
-XX:SurvivorRatio用来设置新生代中eden区和from/to区的比例,
JVM参数中有一个比较重要的参数SurvivorRatio,它定义了新生代中Eden区域和Survivor区域(From幸存区或To幸存区)的比例,默认值为8:1:1(Eden:From:To),也就是说Eden占新生代的8/10,From幸存区和To幸存区各占新生代的1/10
-XX:SurvivorRatio
可参考以下计算公式:
Eden = (R*Y)/(R+1+1)
From = Y/(R+1+1)
To = Y/(R+1+1)
其中:
R:SurvivorRatio比例
Y:新生代空间大小
这里举个例子,如果我们通过设置-Xmn60M来指定新生代分配的空间大小,那么Eden则会分配60M * 0.8 = 48M,Survivor一共分配60M * 0.2 = 12M的内存空间
启动参数配置
-Xmn60M
-XX:SurvivorRatio=8
-XX:+PrintFlagsFinal
控制台输出
uintx NewSize := 62914560 {product}
uintx MaxNewSize := 62914560 {product}
它的含义如下
-XX:MaxTenuringThreshold,从年轻代到老年代,最大晋升年龄。CMS 下默认为 6,G1 下默认为 15
-XX:MaxDirectMemorySize,用于设置直接内存的最大值,限制通过 DirectByteBuffer 申请的内存
-XX:ReservedCodeCacheSize,用于设置 JIT 编译后的代码存放区大小,如果观察到这个值有限制,可以适当调大,一般够用即可
1.2 堆OOM 导出堆的参数配置
参数-XX: +HeapDumpOnOutOfMemoryError 配置堆异常时导出
-XX:HeapDumpPath=./dumplog/dumplog.log 配置都出 堆 dump文件的路径
nohup java -Xms768m -Xmx768m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./dumplog/dumplog.log -jar xxxxxx.jar > logs/xxxxxx.log 2>&1 &
1.3非堆内存的参数配置
nohup java -Xms1g -Xmx1g -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./dumplog/dumplog.log -Xloggc:./dumplog/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=1500m -XX:MaxMetaspaceExpansion=50M -XX:MinMetaspaceExpansion=10M -XX:CompressedClassSpaceSize=1200m -XX:+TraceClassUnloading -XX:+TraceClassLoading -jar xxxx.jar > logs/xxxx.log 2>&1 &
1.3.1方法区配置
在JDK 1.6、JDK 1.7中,方法区可以理解为永久区(Perm)。在JDK 1.8、JDK1.9、JDK1.10中,永久区已经被彻底移除。取而代之的是元数据区,元数据区大小可以使用参数-XX:MaxMetaspaceSize指定(一个大的元数据区可以使系统支持更多的类),这是一块堆外的直接内存
Perm区域的参数配置由-XX:MaxMetaspaceSize 替换
-XX:MaxMetaspaceSize指定永久区的最大可用值
在JDK1.6和JDK1.7等版本中,可以使用-XX:PermSize和-XX:MaxPermSize配置永久区大小
-XX:MetaspaceSize 参数的理解
那么-XX:MetaspaceSize=256m的含义到底是什么呢?其实,这个JVM参数是指Metaspace扩容时触发FullGC的初始化阈值,也是最小的阈值。这里有几个要点需要明确:
如果没有配置-XX:MetaspaceSize,那么触发FGC的阈值是21807104(约20.8m),可以通过jinfo -flag MetaspaceSize pid得到这个值;
如果配置了-XX:MetaspaceSize,那么触发FGC的阈值就是配置的值;
Metaspace由于使用不断扩容到-XX:MetaspaceSize参数指定的量,就会发生FGC;且之后每次Metaspace扩容都可能会发生FGC(至于什么时候会,比较复杂,跟几个参数有关);
如果Old区配置CMS垃圾回收,那么扩容引起的FGC也会使用CMS算法进行回收;如果MaxMetaspaceSize设置太小,可能会导致频繁FullGC,甚至OOM;
任何一个JVM参数的默认值可以通过java -XX:+PrintFlagsFinal -version |grep JVMParamName获取,例如:java -XX:+PrintFlagsFinal -version |grep MetaspaceSize
1.3.1.1 查看方法区的相关参数和设置
[xxx@localhost xxx]$ jps -ml
26732 xxx.jar
[xxx@localhost xxx]$ jinfo -flag CompressedClassSpaceSize 26732
-XX:CompressedClassSpaceSize=528482304
[xxx@localhost xxx]$ jinfo -flag MetaspaceSize 26732
-XX:MetaspaceSize=134217728
[xxx@localhost xxx]$ jinfo -flag MetaspaceSize 26732^C
[xxx@localhost xxx]$ jinfo -flag MaxMetaspaceSize 26732
-XX:MaxMetaspaceSize=536870912
[xxx@localhost xxx]$ jinfo -flag MinMetaspaceFreeRatio 26732
-XX:MinMetaspaceFreeRatio=40
[xxx@localhost xxx]$ jinfo -flag MaxMetaspaceFreeRatio 26732
-XX:MaxMetaspaceFreeRatio=70
[xxx@localhost xxx]$ jinfo -flag CompressedClassSpaceSize 26732
-XX:CompressedClassSpaceSize=528482304
[xxx@localhost xxx]$ jinfo -flag InitialBootClassLoaderMetaspaceSize 26732
-XX:InitialBootClassLoaderMetaspaceSize=4194304
1.3.1.2 查看方法区的相关参数和设置
Metaspace使用的是本地内存,而不是堆内存,也就是说在默认情况下Metaspace的大小只与本地内存大小有关。当然你也可以通过以下的几个参数对Metaspace进行控制:
-XX:MetaspaceSize=N
这个参数是初始化的Metaspace大小,该值越大触发Metaspace GC的时机就越晚。随着GC的到来,虚拟机会根据实际情况调控Metaspace的大小,可能增加上线也可能降低。在默认情况下,这个值大小根据不同的平台在12M到20M浮动。使用java -XX:+PrintFlagsInitial命令查看本机的初始化参数,-XX:Metaspacesize为21810376B(大约20.8M)。
-XX:MaxMetaspaceSize=N
这个参数用于限制Metaspace增长的上限,防止因为某些情况导致Metaspace无限的使用本地内存,影响到其他程序。在本机上该参数的默认值为4294967295B(大约4096MB)。
-XX:MinMetaspaceFreeRatio=N
当进行过Metaspace GC之后,会计算当前Metaspace的空闲空间比,如果空闲比小于这个参数,那么虚拟机将增长Metaspace的大小。在本机该参数的默认值为40,也就是40%。设置该参数可以控制Metaspace的增长的速度,太小的值会导致Metaspace增长的缓慢,Metaspace的使用逐渐趋于饱和,可能会影响之后类的加载。而太大的值会导致Metaspace增长的过快,浪费内存。
-XX:MaxMetasaceFreeRatio=N
当进行过Metaspace GC之后, 会计算当前Metaspace的空闲空间比,如果空闲比大于这个参数,那么虚拟机会释放Metaspace的部分空间。在本机该参数的默认值为70,也就是70%。
-XX:MaxMetaspaceExpansion=N
Metaspace增长时的最大幅度。在本机上该参数的默认值为5452592B(大约为5MB)。
-XX:MinMetaspaceExpansion=N
Metaspace增长时的最小幅度。在本机上该参数的默认值为340784B(大约330KB为)。
以前只认为,Metaspace区是保存在本地内存中,是没有上限的,经查阅资料才发现,原来JDK8中,XX:MaxMetaspaceSize确实是没有上限的,最大容量与机器的内存有关;但是XX:MetaspaceSize是有一个默认值的:21M
-XX:CompressedClassSpaceSize 设置方法区类信息加载空间的大小,因为 CompressedClassSpaceSize的大小是由:MaxMetaspaceSize,InitialBootClassLoaderMetaspaceSize,CompressedClassSpaceSize这三个参数共同影响的结果。具体就是:min_metaspace_sz 加CompressedClassSpaceSize大于 MaxMetaspaceSize的时候,CompressedClassSpaceSize就强制被设置为(MaxMetaspaceSize - min_metaspace_sz)。64位下默认4M,32位下默认2200K
-XX:InitialBootClassLoaderMetaspaceSize 设置类信息区,引导类的元空间大小
1.3.1.3 查看类加载与卸载时候的信息
我增加了如下两个JVM启动参数来观察类的加载、卸载信息:
-XX:TraceClassLoading -XX:TraceClassUnloading
nohup java -Xms1g -Xmx1g -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./dumplog/dumplog.log -Xloggc:./dumplog/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=1500m -XX:MaxMetaspaceExpansion=50M -XX:MinMetaspaceExpansion=10M -XX:CompressedClassSpaceSize=1200m -XX:+TraceClassUnloading -XX:+TraceClassLoading -jar xxxx.jar > logs/xxx.log 2>&1 &
1.3.2 栈配置
-Xss参数指定线程的栈大小
1.3.2 直接内存配置
参数 -XX:MaxDirectMemorySize
-XX:MaxMetaspaceSize,元空间最大值
-XX:MaxDirectMemorySize,用于设置直接内存的最大值,限制通过 DirectByteBuffer 申请的内存
-XX:ReservedCodeCacheSize,用于设置 JIT 编译后的代码存放区大小,如果观察到这个值有限制,可以适当调大,一般够用即可
1.4 GC 垃圾回收器常见参数
1.4.1 与串行回收器相关的参数
·-XX:+UseSerialGC:在新生代和老年代使用串行回收器。
·-XX:SurvivorRatio:设置eden区大小和survivior区大小的比例。
·-XX:PretenureSizeThreshold:设置大对象直接进入老年代的阈值。当对象的大小超过这个值时,将直接被分配在老年代。
·-XX:MaxTenuringThreshold:设置对象进入老年代的年龄的最大值。每一次 Minor GC后,对象年龄就加1。任何大于这个年龄的对象,一定会进入老年代。
1.4.2.与并行GC相关的参数
·-XX:+UseParNewGC(考虑到兼容性问题,JDK 9、JDK 10已经删除):在新生代使用并行回收器。
·-XX:+UseParallelOldGC:老年代使用并行回收器。
·-XX:ParallelGCThreads:设置用于垃圾回收的线程数。通常情况下可以和CPU数量相等,但在CPU数量比较多的情况下,设置相对较小的数值也是合理的。
·-XX:MaxGCPauseMillis:设置最大垃圾回收停顿时间。它的值是一个大于0的整数。回收器在工作时,会调整 Java 堆大小或者其他一些参数,尽可能地把停顿时间控制在MaxGCPauseMillis以内。
·-XX:GCTimeRatio:设置吞吐量大小。它的值是一个 0 到 100之间的整数。假设GCTimeRatio的值为n ,那么系统将花费不超过1/(1+n )的时间用于垃圾回收。
·-XX:+UseAdaptiveSizePolicy:打开自适应GC策略。在这种模式下,新生代的大小、eden区和survivior区的比例、晋升老年代的对象年龄等参数会被自动调整,以达到在堆大小、吞吐量和停顿时间之间的平衡。
开启:-XX:+UseAdaptiveSizePolicy
关闭:-XX:-UseAdaptiveSizePolicy
JDK 1.8 默认使用 UseParallelGC 垃圾回收器,该垃圾回收器默认启动了 AdaptiveSizePolicy,会根据GC的情况自动计算计算 Eden、From 和 To 区的大小。
注意事项: 1、在 JDK 1.8 中,如果使用 CMS,无论 UseAdaptiveSizePolicy 如何设置,都会将
UseAdaptiveSizePolicy 设置为 false;不过不同版本的JDK存在差异;
2、UseAdaptiveSizePolicy不要和SurvivorRatio参数显示设置搭配使用,一起使用会导致参数失效;
3、由于AdaptiveSizePolicy会动态调整 Eden、Survivor 的大小,有些情况存在Survivor
被自动调为很小,比如十几MB甚至几MB的可能,这个时候YGC回收掉 Eden区后,还存活的对象进入Survivor
装不下,就会直接晋升到老年代,导致老年代占用空间逐渐增加,从而触发FULL GC,如果一次FULL
GC的耗时很长(比如到达几百毫秒),那么在要求高响应的系统就是不可取的。
1.4.3.与CMS回收器相关的参数(JDK9、JDK10已经开始废弃CMS回收器,建议使用G1回收器)
·-XX:+UseConcMarkSweepGC:新生代使用并行回收器,老年代使用CMS+串行回收器。
·-XX:ParallelCMSThreads:设定CMS的线程数量。
·-XX:CMSInitiatingOccupancyFraction:设置 CMS 回收器在老年代空间被使用多少后触发,默认为68%。
·-XX:+UseCMSCompactAtFullCollection:设置 CMS 回收器在完成垃圾回收后是否要进行一次内存碎片的整理。
·-XX:CMSFullGCsBeforeCompaction:设定进行多少次CMS垃圾回收后,进行一次内存压缩。
·-XX:+CMSClassUnloadingEnabled:允许对类元数据区进行回收。
·-XX:CMSInitiatingPermOccupancyFraction:当永久区占用率达到这一百分比时,启动CMS回收(前提是激活了-XX:+CMSClassUnloadingEnabled)。
·-XX:UseCMSInitiatingOccupancyOnly:表示只在到达阈值的时候才进行CMS回收。
·-XX:+CMSIncrementalMode:使用增量模式,比较适合单CPU。增量模式在JDK8中标记为废弃,并且将在JDK9中彻底移除。
1.4.4.与G1回收器相关的参数
·-XX:+UseG1GC:使用G1回收器。
·-XX:MaxGCPauseMillis:设置最大垃圾回收停顿时间。
·-XX:GCPauseIntervalMillis:设置停顿间隔时间。
1.4.5.TLAB相关
·-XX:+UseTLAB:开启TLAB分配。
·-XX:+PrintTLAB(考虑到兼容性问题,JDK 9、JDK 10不再支持此参数):打印TLAB相关分配信息。
·-XX:TLABSize:设置TLAB区域大小。
·-XX:+ResizeTLAB:自动调整TLAB区域大小。
1.4.6.其他参数
·-XX:+DisableExplicitGC:禁用显式GC。
·-XX:+ExplicitGCInvokesConcurrent:使用并发方式处理显式GC。
1.5 GC 日志打印
1.5.1 JDK8 GC 日志打印参数
-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+UseSerialGC -Xmx1m -Xloggc:./gc-serial.log
参数 功能
-XX:+PrintGC 使用这个参数启动Java虚拟机后,只要遇到GC,就会打印日志
-XX:+PrintGCDetails 输出GC的详细日志,参数-XX:+PrintGCDetails还会使虚拟机在退出前打印堆的详细信息,详细信息描述了当前堆的各个区间的使用情况
-XX:+PrintGCTimeStamps 输出GC的时间戳(以基准时间的形式)
-XX:+PrintGCDateStamps 输出GC的时间戳(以日期的形式,如 2013-05-04T21:53:59.234+0800)
-XX:+PrintHeapAtGC 在进行GC的前后打印出堆的信息。还可以使用参数-XX:+PrintHeapAtGC(考虑到兼容性,从JDK9开始已经删除此参数,查看堆信息可以使用VisualVM,第6章将会讲述)
-Xloggc:gc.log 日志文件的输出路径
该日志显示,一共进行了4次GC,每次GC占用一行,在GC前,堆空间使用量约为4MB,在GC后,堆空间使用量为377KB,当前可用的堆空间总和约为16MB(15936KB)。最后,显示的是本次GC所
花的时间。
1.5.2 JDK9、JDK10 GC日志参数
.-XX:+PrintGC(在JDK9、JDK10中建议使用-Xlog:gc),使用这个参数启动Java虚拟机后,只要遇到GC,就会打印日志,JDK9、JDK10默认使用G1作为垃圾回收器,使用参数-Xlog:gc来打印GC日志
-Xlog:gc* 打印GC 日志详情,JDK9、JDK10建议使用-Xlog:gc*
-XX:+PrintHeapAtGC 在进行GC的前后打印出堆的信息。还可以使用参数-XX:+PrintHeapAtGC(考虑到兼容性,从JDK9开始已经删除此参数,查看堆信息可以使用VisualVM,第6章将会讲述)
从这个输出中可以看到,系统经历了3次GC,第1次仅为新生代GC,回收的效果是新生代从回收前的8MB左右降低到1MB。整个堆从22MB左右降低到17MB。
第2次(加粗部分)为Full GC,它同时回收了新生代、老年代和永久区。日志显示,新生代在这次GC中没有释放空间(严格来说,这是GC日志的一个小bug,事实上,在这次FullGC完成后,新生代被清空,由于GC日志输出时机的关系,各个版本JDK的日志多少有些不太精确的地方,读者需要留意),老年代从16MB降低到13MB。整个堆大小从26MB左右降低为13MB左右(这个大小完全与老年代
实际大小相等,因此也可以推断,新生代实际上已被清空)。永久区的大小没有变化。日志的最后显示了GC所花的时间,其中user表示用户态CPU耗时,sys表示系统CPU耗时,real表示GC实际经历的时间。
透过日志看垃圾收集器
Serial收集器:新生代显示 “[DefNew”,即 Default New Generation
ParNew收集器:新生代显示“[ParNew”,即 Parallel New Generation Parallel
Scavenge收集器:新生代显示"[PSYoungGen",JDK1.7使用的即PSYoungGen Parallel
Old收集器:老年代显示"[ParoldGen" G1收集器:显示”garbage-first heap“
1.6 GC 日志分析
参考 https://www.cnblogs.com/dtyy/p/15873735.html
参考 https://blog.csdn.net/xyz9353/article/details/119190661
更多推荐
所有评论(0)