【JVM】JVM参数配置

JVM参数配置

我们学习JavaGC机制的目的是为了实用,也就是为了在JVM出现问题的时候分析原因并解决之,JVM监控与调优主要的着眼点在于如何配置、如何监控、如何优化3点上。

在Java虚拟机的参数中,有三种表示方法

  • 1、标准参数(-),所有的 JVM 实现都必须实现这些参数的功能,而且向后兼容;

  • 2、非标准参数(-X),默认 JVM 实现这些参数的功能,但是并不保证所有 JVM 实现都满足,且不保证向后兼容;

  • 3、非Stable参数(-XX),此类参数各个 JVM 实现会有所不同,将来可能会随时取消,需要慎重使用(但是,这些参数往往是非常有用的);

本文只重点介绍一些重要和常用的参数,如果想了解全部参数,可以参考下面的文章:
JVM启动参数大全

1、标准参数

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

-client

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

-server

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

  • 默认情况下,不同的启动模式,执行GC的方式有所区别:
启动模式新生代GC 方式旧生代和持久代 GC 方式
client串行串行
server并行并发
-classpath / -cp

JVM加载和搜索文件的目录路径,多个路径用;分隔。注意,如果使用了- classpath,JVM就不会再搜索环境变量中定义的CLASSPATH路径。

  • JVM搜索路径的顺序为:
    • 1.先搜索JVM自带的jar或zip包(Bootstratp搜索路径可以用System.getProperty(“sun.boot.class.path”)获得)
    • 2.搜索JRE_HOME/lib/ext下的jar包(Extension搜索路径可以用System.getProperty(“java.ext.dirs”)获得)
    • 3.搜索用户自定义目录,顺序为:当前目录(.),CLASSPATH,-cp(搜索路径System.getProperty(“java.class.path”)获得)
-DpropertyName=value

定义系统的全局属性值,如配置文件地址等,如果value有空格,可以用-Dname="space string"这样的形式来定义,用System.getProperty(“propertyName”)可以获得这些定义的属性值,在代码中也可以用System.setProperty(“propertyName”,“value”)的形式来定义属性。

-verbose

这是查询GC问题最常用的命令之一,具体参数如:-verbose:class
输出jvm载入类的相关信息,当jvm报告说找不到类或者类冲突时可此进行诊断。-verbose:gc
输出每次GC的相关情况,后面会有更详细的介绍。

-verbose:jni

输出native方法调用的相关情况,一般用于诊断jni调用错误信息。

2、非标准参数

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

在不同类型的JVM中,采用的参数有所不同
在这里插入图片描述

-Xmn

新生代内存大小,包括E区和两个S区的总和,使用方法如:-Xmn65535,-Xmn1024k,-Xmn512m,-Xmn1g
(-Xms,-Xmx也是种写法)

-Xms

初始堆的大小,也是堆大小的最小值,默认值是总共的物理内存/64(且小于1G),默认情况下,当堆中可用内存小于40%(这个值可以用-XX:
MinHeapFreeRatio 调整,如-X:MinHeapFreeRatio=30)时,堆内存会开始增加,一直增加到-Xmx的大小;

-Xmx

堆的最大值,默认值是总共的物理内存/64(且小于1G),如果Xms和Xmx都不设置,则两者大小会相同,默认情况下,当堆中可用内存大于70%(这个值可以用-XX:
MaxHeapFreeRatio 调整,如-X:MaxHeapFreeRatio=60)时,堆内存会开始减少,一直减小到-Xms的大小;

整个堆的大小=年轻代大小+年老代大小,堆的大小不包含持久代大小,如果增大了年轻代,年老代相应就会减小,官方默认的配置为年老代大小/年轻代大小=2/1左右(使用-XX:NewRatio可以设置-XX:NewRatio=5,表示年老代/年轻代=5/1);

建议在开发测试环境可以用Xms和Xmx分别设置最小值最大值,但是在线上生产环境,Xms和Xmx设置的值必须一样,原因与年轻代一样——防止抖动;

-Xss

这个参数用于设置每个线程的栈内存,默认1M

-Xprof

跟踪正运行的程序,并将跟踪数据在标准输出;适合于开发环境调试。

-Xnoclassgc

关闭针对class的gc功能;因为其阻止内存回收,所以可能会导致OutOfMemoryError错误,慎用;

-Xincgc

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

-Xloggc:file

与-verbose:gc功能类似,只是将每次GC事件的相关情况记录到一个文件中,文件的位置最好在本地,以避免网络的潜在问题。
 
若与verbose命令同时出现在命令行中,则以-Xloggc为准。

3、非Stable参数(非静态参数)

以-XX表示的非Stable参数, JVM(Hotspot)中主要的参数可以大致分为3类

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

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

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

(1)性能参数

性能参数往往用来定义内存分配的大小和比例,相比于行为参数和调试参数,一个比较明显的区别是性能参数后面往往跟的有数值,常用如下:

参数及其默认值描述
-XX:NewSize=2.125m新生代对象生成时占用内存的默认值
-XX:MaxNewSize=size新生代对象能占用内存的最大值
-XX:MaxPermSize=64m方法区所能占用的最大内存(非堆内存)
-XX:PermSize=64m方法区分配的初始内存
-XX:MaxTenuringThreshold=15对象在新生代存活区切换的次数(坚持过MinorGC 的次数,每坚持过一次,该值就增加1),大于该值会进入老年代
-XX:MaxHeapFreeRatio=70GC后Java堆中空闲量占的最大比例,大于该值,则堆内存会减少
-XX:MinHeapFreeRatio=40GC后Java堆中空闲量占的最小比例,小于该值,则堆内存会增加
-XX:NewRatio=2新生代内存容量与老生代内存容量的比例
-XX:ReservedCodeCacheSize=32m保留代码占用的内存容量
-XX:ThreadStackSize=512设置线程栈大小,若为 0 则使用系统默认值
-XX:LargePageSizeInBytes=4m设置用于Java堆的大页面尺寸
-XX:PretenureSizeThreshold=size大于该值的对象直接晋升入老年代(这种对象少用为好)
-XX:SurvivorRatio=8Eden 区域 Survivor 区的容量比值,如默认值为8,代表 Eden : Survivor1 : Survivor2 = 8 : 1 : 1

(2)行为参数

行为参数主要用来选择使用什么样的垃圾收集器组合,以及控制运行过程中的GC策略等

参数及其默认值描述
-XX:+UseSerialGC启用串行 GC,即采用 Serial + Serial Old 模式
-XX:+UseParallelGC启用并行 GC,即采用 Parallel scavenge + Serial Old 收集器组合(-Server 模式下的默认组合
-XX:GCTimeRatio=99设置用户执行时间占总时间的比例(默认值 99,即1%的时间用于 GC)
-XX:MaxGCPauseMillis=time设置 GC 的最大停顿时间(这个参数只对 Parallel Scavenge 有效)
-XX:+UseParNewGC使用 ParNew + Serial Old 收集器组合
-XX:ParallelGCThreads设置执行内存回收的线程数,在 + UseParNewGC 的情况下使用
-XX:+UseParallelOldGC使用 Parallel Scavenge + Parallel Old 组合收集器
-XX:+UseConcMarkSweepGC使用 ParNew + CMS + Serial Old 组合并发收集,优先使用 ParNew + CMS,当用户线程内存不足时,采用备用方案 Serial Old 收集
-XX:-DisableExplicitGC禁止调用 System.gc();但 JVM 的 GC 仍然有效
-XX:+ScavengeBeforeFullGC新生代 GC 优先于 Full GC 执行

(3)调试参数

调试参数,主要用于监控和打印GC的信息

参数及其默认值描述
-XX:-CITime打印消耗在 JIT 编译的时间
-XX:ErrorFile=./hs_err_pid< pid >.log保存错误日志或者数据到文件中
-XX:-ExtendedDTraceProbes开启 solaris 特有的 dtrace 探针
-XX:HeapDumpPath=./java_pid< pid >.hprof指定导出堆信息时的路径或文件名
-XX:-HeapDumpOnOutOfMemoryError当首次遭遇 OOM 时导出此时堆中相关信息
-XX:OnError="< cmd args >;< cmd args >" 出现致命 ERROR 之后运行自定义命令-XX:OnOutOfMemoryError="< cmd args >;< cmd args >"当首次遭遇 OOM 时执行自定义命令
-XX:-PrintClassHistogram遇到 Ctrl-Break 后打印类实例的柱状信息,与 jmap -histo 功能相同
-XX:-PrintConcurrentLocks遇到 Ctrl-Break 后打印并发锁的相关信息,与 jstack -l 功能相同
-XX:-PrintCommandLineFlags打印在命令行中出现过的标记
-XX:-PrintComlilation当一个方法被编译时打印相关信息
-XX:-PrintGC每次 GC 时打印相关信息
-XX:-PrintGC Details每次 GC 时打印详细信息
-XX:-PrintGCTimeStamps打印每次 GC 的时间戳
-XX:-TraceClassLoading跟踪类的加载信息
-XX:-TraceClassLoadingPreorder跟踪被引用的所有类的加载信息
-XX:-TraceClassResolution跟踪常量池
-XX:-TraceClassUnloading跟踪类的卸载信息
-XX:-TraceLoadingConstraints跟踪类加载器约束的相关信息

JVM调优

JVM调优原则

  • 1、多数的java应用不需要在服务器上进行GC调优
  • 2、多数的导致GC问题的Java应用,不是参数设置出错,而是代码问题
  • 3、减少创建对象的数量
  • 4、减少使用全局变量和大对象
  • 5、在实际过程中,分析GC情况优化代码比优化GC参数要多得多

优化目的

  • 减少Full GC的执行时间
  • 将转移到老年代的对象数量降到最低

调优的一般步骤

1、监控GC的状态

使用各种JVM工具,查看当前日志,分析JVM参数的设置,分析堆内存快照和GC日志,根据实际的各区域的内存划分和GC的执行时间,判断是否需要进行优化

2、分析结果、判断是否需要优化

如果各项参数设置合理,系统没有超时的日志出现,GC频率也不高,GC耗时不高,就没有必要进行GC优化了,GC时间超过1~3秒,或者频繁GC,则必须要进行优化
 
注:如果满足下面的指标,则一般不需要进行GC:
Minor GC时间不到50ms
Minor GC执行不频繁,约10秒一次(在10秒内考虑优化)
Full GC执行时间不到1s
Full GC 执行不频繁,不低于10分钟一次

3、调整GC类型或内存分配

如果内存分配过大或过小,或者是采用GC收集器比较慢,则应该优先调整这些参数
给找到几台机器进行对别,对优化后的机器和优化前的机器进行性能比对,并针对性作出选择

4、不断的分析和调整

通过不断的实验和试错,分析并找到最合理的参数

5、全面应用参数

如果找到最合理的参数,则将参数应用到服务器,并进行后续跟踪

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值