JVM优化——JVM参数讲解(06)

JVM默认有好多参数,但是好多都是没有启用的,或者有些是在JVM启动的时候设置了一些默认值,假如我们能指定某些参数的值或者启用某些JVM监控参数的设置,这对我们以后JVM的调优将有很大帮助。

JVM参数大约有三种表示方法:

  1. 标准参数(-),所有的JVM实现都必须实现这些参数的功能,而且向后兼容;
  2. 非标准参数(-X),默认jvm实现这些参数的功能,但是并不保证所有jvm实现都满足,且不保证向后兼容;
  3. 非稳定参数(-XX),此类参数各个jvm实现会有所不同,将来可能会随时取消,需要慎重使用(但是,这些参数往往是非常有用的);
标准参数

其实标准参数是用过Java的人都最熟悉的,如java -version, java -jar等,输入命令java -help或java -?就能获得当前机器所有java的标准参数列表。

-client
设置jvm使用client模式,这是一般在pc机器上使用的模式,启动很快,但性能和内存管理效率并不高;多用于桌面应用。

-server
使用server模式,启动速度虽然慢,但是性能和内存管理效率很高,适用于服务器,用于生成环境、开发环境或测试环境的服务端;
如果没有指定-server或-client,JVM启动的时候会自动检测当前主机是否为服务器,如果是就以server模式启动,64位的JVM只有server模式,所以无法使用-client参数;

-DprotertyName=value
定义系统的全局属性值,如果value有空格,可以用-Dname=”space string”这样的形式来定义,用System.getProperty(“propertyName”)可以获得这些定义的属性值。

非标准参数

非标准参数,是在标准参数的基础上进行扩展的参数,输入“java -X”命令,能够获得当前JVM支持的所有非标准参数列表,其实仔细一看并不多。

-Xnoclassgc 关闭针对class的gc功能,因为其阻止内存回收,可能导致内存溢出。

-Xincgc 开启增量gc(默认为关闭);这有助于减少长时间GC时应用程序出现的停顿;但由于可能和应用程序并发执行,所以会降低CPU对应用的处理能力。

-Xloggc:file 与-verbose:gc功能类似,只是将每次GC事件的相关情况记录到一个文件中。若与verbose命令同时出现在命令行中,则以-Xloggc为准。

非稳定参数(非静态参数)

以-XX表示的非Stable参数,虽然在官方文档中是不确定的,不健壮的,各个公司的实现也各有不同,但往往非常实用,所以这部分参数对于GC非常重要。JVM(Hotspot)中主要的参数可以大致分为3类:

  • 性能参数(Performance Options):用于JVM的性能调优和内存分配控制,如初始化内存大小的设置;
  • 行为参数(Behavioral Options):用于改变JVM的基础行为,如GC的方式和算法的选择;
  • 调试参数(Debugging Options):用于监控、打印、输出等jvm参数,用于显示jvm更加详细的信息;

对于非稳定参数,使用方法有4种:

  • -XX:+option 启用选项
  • -XX:-option 不启用选项
  • -XX:option=number 给选项设置一个数字类型值,可跟单位,例如 32k, 1024m, 2g
  • -XX:option=string 给选项设置一个字符串值,例如-XX:HeapDumpPath=./dump.core
1. 堆内存配置

-Xms3G 设置JVM初始堆内存大小为3G
-Xmx3G 设置JVM最大堆内存大小为3G,一般此值和-Xms相等,防止每次GC之后都要调整堆的大小,即:抖动,抖动会严重影响性能。
-Xmn2G 设置年轻代的大小为2G(JDK1.4之前不适用)
-XX:NewSize 设置新生代的大小
-XX:MaxNewSize 设置新生代的最大值,如果设置了-Xmn和-XX:NewSize,-XX:MaxNewSize则谁在后面谁就生效,一般只设置-Xmn即可。
-Xss256K 设置每个线程的堆栈大小,JDK5.0之后默认为1M。
-XX:PermSize=32M 方法区分配的初始内存(JDK8已不再使用)
-XX:MaxPermSize=32M 方法区分配的最大内存(JDK8已不再使用)
-XX:MaxTenuringThreshold=15 指定对象经过多少次YoungGC之后直接进入老年代,默认15
-XX:NewRatio=2 新生代和老年代的内存容量比例
-XX:ThreadStackSize=512 设置线程栈的大小,若为0则表示使用系统默认值
-XX:PretenureSizeThreshold 大约该值的对象直接进入老年代
-XX:SurviviorRatio=8 Eden区域与Survivior区域的容量比例,默认为8

2. 垃圾回收统计信息的设置

-XX:+PrintGC 开启简单的GC日志模式
-XX:+PrintGCDetails 开启详细的GC日志模式
-XX:+PrintHeapAtGC 每次GC时打印堆信息
-XX:+PrintGCTimeStamps 将时间加到GC日志中
-XX:+PrintGCDateStamps 将日期加到GC日志中
-Xloggc=/path/to/file 将日志信息输出到指定文件

3. JVM监控参数设置

-XX:+PrintFlagsFinal 输出-XX参数的值
-XX:+PrintFlagsInitial 输出-XX参数的初始值
-XX:+PrintCommandLineFlag 输出已被用户设置过的一些参数名称和值(建议设置)
-XX:+HeapDumpOnOutOfMemoryError 在JVM发生内存溢出的时候自动生成堆内存快照
-XX:HeapDumpPath=/path/to/file JVM内存溢出堆内存快照保存的位置
-XX:OnOutOfMemoryError 当内存溢出时,执行某些指令,例如发Email等
-XX:+NeverTenure 表示永远不会晋升到老年代,风险较大,且浪费一半堆内存,不建议设置
-XX:+AlwaysTenure 表示没有幸存区,即所有对象第一次GC时,就晋升到老年代

4. 垃圾收集器设置

-XX:+UseSerialGC 设置使用串行垃圾收集器
-XX:+UseParNewGC 设置使用ParNew垃圾收集器
-XX:ParallelGCThreads 设置执行垃圾回收的线程数
-XX:+UseParallelGC 设置使用Parallel Scavenge收集器
-XX:MaxGCPauseMillis 设置GC的最大停顿时间
-XX:+UserParallelOldGC 设置老年代使用并行收集器
-XX:+UseConcMarkSweepGC 设置老年代使用CMS(并发)收集器

坚持原创技术分享,您的支持将鼓励我的继续创作