JVM 常见配置参数

JVM 配置常见参数

Java虚拟机的参数,在启动jar包的时候通过java 命令指定JVM参数

-options表示Java虚拟机的启动参数,class为带有main()函数的Java类,args表示传递给主函数main()的参数。

一、系统查看参数:

-XX:+PrintVMOptions可以在程序运行时打印虚拟机接收到

-XX:+PrintCommandLineFlags可以打印传递给虚拟机的显式和隐式参数,打印出包括配置文件在内的配置

-XX:+PrintFlagsFinal,它会打印所有的系统参数的值

java -XX:+PrintCommandLineFlags -version

1.1.1 查看当前系统的垃圾回收器使用的是哪种

bash 复制代码
jinfo -flags [进程pid]

找到-useXXXX这样的参数,参数后即为所使用的GC回收器

bash 复制代码
[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:SurvivorRatio用来设置新生代中eden区和from/to区的比例

-XX:SurvivorRatio可以设置eden区与survivor的比例。-

-XX:NewRatio可以设置老年代与新生代的比例。

参数-Xmn可以用于设置新生代的大小。设置一个较大的新生代会减小老年代的大小,这个参数对系统性能及GC行为有很大的影响。新生代的大小一般设置为整个堆空间的1/3到1/4。

参数-XX:SurvivorRatio用来设置新生代中eden区和from/to区的比例,它的含义如下

在JDK 1.6、JDK 1.7中,方法区可以理解为永久区(Perm)。在JDK 1.8、JDK1.9、JDK1.10中,永久区已经被彻底移除。取而代之的是元数据区,元数据区大小可以使用参数-XX:MaxMetaspaceSize指定(一个大的元数据区可以使系统支持更多的类),这是一块堆外的直接内存

Perm区域的参数配置由-XX:MaxMetaspaceSize 替换

1.2 堆OOM 导出堆的参数配置

参数-XX: +HeapDumpOnOutOfMemoryError 配置堆异常时导出

-XX:HeapDumpPath=./dumplog/dumplog.log 配置都出 堆 dump文件的路径

bash 复制代码
nohup java -Xms768m -Xmx768m  -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./dumplog/dumplog.log    -jar xxxxxx.jar > logs/xxxxxx.log 2>&1 &

1.3非堆内存的参数配置

1.3.1方法区配置

-XX:MaxMetaspaceSize指定永久区的最大可用值

在JDK1.6和JDK1.7等版本中,可以使用-XX:PermSize和-XX:MaxPermSize配置永久区大小

1.3.1.1 查看方法区的相关参数和设置
bash 复制代码
[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启动参数来观察类的加载、卸载信息:

bash 复制代码
-XX:TraceClassLoading -XX:TraceClassUnloading
bash 复制代码
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

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区的比例、晋升老年代的对象年龄等参数会被自动调整,以达到在堆大小、吞吐量和停顿时间之间的平衡。

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 日志打印参数

bash 复制代码
-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

相关推荐
yuanbenshidiaos6 小时前
c++---------数据类型
java·jvm·c++
java1234_小锋9 小时前
JVM对象分配内存如何保证线程安全?
jvm
40岁的系统架构师12 小时前
1 JVM JDK JRE之间的区别以及使用字节码的好处
java·jvm·python
寻找沙漠的人13 小时前
理解JVM
java·jvm·java-ee
我叫啥都行13 小时前
计算机基础复习12.22
java·jvm·redis·后端·mysql
bufanjun00116 小时前
JUC并发工具---ThreadLocal
java·jvm·面试·并发·并发基础
东阳马生架构1 天前
JVM简介—1.Java内存区域
jvm
工程师老罗1 天前
Android笔试面试题AI答之SQLite(2)
android·jvm·sqlite
Qzer_4071 天前
jvm字节码中方法的结构
jvm
奇偶变不变2 天前
RTOS之事件集
java·linux·jvm·单片机·算法