JVM 调优 (5) -- 常用的 JVM 参数

1. JVM 参数简介

在Java虚拟机的参数中,其实可以把这些参数分为三类,当然,这是针对JDK1.6来说的,如果对于JDK1.8,那么就不是这么分类的了,但是,由于这两个版本很多常用的参数的差别是不大的,所以这篇文章就先介绍JDK1.6的VM参数。

主要可以分为以下三类:

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

虽然是这么分类的,实际上呢,非标准参数和非稳定的参数实际的使用中还是用的非常的多的。

1. 标准参数

比如 java -version、java -jar 等等,我们在 CMD 中输入 java -help 就可以获得 Java 当前版本的所有标准参数了。
以 JDK 1.8 为例:
在这里插入图片描述

1. -client & -server

-client:以 client 模式启动 JVM,这种方式启动速度快,但运行时性能和内存管理效率不高,适合客户端程序或者开发调试。

-server:以 server 模式启动 JVM,与 -client 情况恰好相反。适合生产环境,适用于服务器。64 位的 JVM 自动以 server 模式启动。

2. -classpath 或者 -cp

-classpath/-cp:通知 JVM 类搜索路径。如果指定了-classpath,则 JVM 就忽略 CLASSPATH 中指定的路径。各路径之间以分号隔开。如果 -classpath 和 CLASSPATH 都没有指定,则 JVM 从当前路径寻找 class。

JVM 搜索路径的顺序:

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

测试:

System.out.println(System.getProperty("sun.boot.class.path"));
System.out.println(System.getProperty("java.ext.dirs"));
System.out.println(System.getProperty("java.class.path"));

在这里插入图片描述

3. -DpropertyName=value

定义系统的全局属性值,如配置文件地址等,如果 value 有空格,则需要使用双引号。

另外用System.getProperty("hello")可以获得这些定义的属性值,在代码中也可以用System.setProperty("hello","world")的形式来定义属性。

如:propertyName 为 hello,value 为 wa ha ha
在这里插入图片描述

System.out.println(System.getProperty("hello"));

//输出
wa ha ha
4. -verbose

查询 GC 问题最常用的命令之一,参数如下:

  1. -verbose:class,输出 JVM 载入类的相关信息,当 JVM 报告说找不到类或者类冲突时可以进行诊断。
  2. -verbose:gc,输出每次 GC 的相关情况。
  3. -verbose:jni,输出 native 方法调用的相关情况,一般用于诊断 jni 调用错误信息。
  4. 控制台输出 GC 信息还可以使用如下命令:-XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCApplicationStoppedTime,按照参数的顺序分别输出GC的简要信息,GC的详细信息、GC的时间信息及GC造成的应用暂停的时间。

2. 非标准参数

非标注的参数主要是关于 Java 内存区域的设置参数,非标准参数其实是在标准参数的基础上的一些扩充参数,可以输入 java -X,可以获得当前 JVM 支持的非标准参数。
以 JDK 1.8 为例:
在这里插入图片描述

1. -Xmn & -Xms & -Xmx & -Xss

-Xmn:新生代内存大小的最大值,包括 E 区和两个 S 区的总和。如:-Xmn512m、-Xmn2g

-Xms:初始堆的大小 ,也是堆的最小值,默认值是总的物理内存的 1/64(且小于1G)。默认情况下,当堆中可用内存小于40%,堆内存会开始增加,一直增加到 -Xmx 的大小

-Xmx:堆的最大值,默认值是总的物理内存的 1/64(且小于1G),默认情况下,当堆中可用内存大于 70%,堆内存会开始减少,一直减小到 -Xms 的大小。

为了避免这种浮动,所以在设置 -Xms 和 -Xmx 参数时,一般会设置成一样的,能够提高性能。

另外,官方默认的配置为年老代大小:年轻代大小=2:1,使用 -XX:NewRatio 可以设置年老代和年轻代之比,如:-XX:NewRatio=4,表示年老代:年轻代=4:1,可以使用 -XX:SurvivorRatio 来指定 Eden 与 Survivor 的比值,如:-XX:SurvivorRatio=8,表示 Eden:S0:S1=8:1:1

-Xss:设置每个线程的栈内存,默认1M,一般来说是不需要改的。

2. -Xprof & -Xnoclassgc & -Xincgc & -Xloggc:file

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

-Xnoclassgc:禁用类垃圾收集,关闭针对 class 的 gc 功能;因为其阻止内存回收,所以可能会导致 OutOfMemoryError 错误,慎用。

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

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

3. -Xint & -Xcomp & -Xmixed

-Xint:在解释模式(interpreted mode)下,-Xint 标记会强制 JVM 执行所有的字节码,这会降低运行速度,通常低 10 倍或更多。

-Xcomp:与 -Xint 正好相反,JVM 在第一次使用时会把所有的字节码编译成本地代码,从而带来最大程度的优化。然而,很多应用在使用 -Xcomp 也会有一些性能的损失,当然这比使用 -Xint 损失的少,原因是 -xcomp 没有让 JVM 启用 JIT 编译器的全部功能。JIT 编译器可以对是否需要编译做判断,如果所有代码都进行编译的话,对于一些只执行一次的代码就没有意义了。

-Xmixed:-Xmixed 是混合模式,这是 JVM 默认的模式,也是推荐使用的模式。将解释模式与编译模式进行混合使用,由 JVM 自己决定。

3. 非Stable参数

这类参数你一看官网以为不能使用呢,官网给你的建议就是这些参数不稳定,慎用,其实这主要的原因还是因为每个公司的实现都是不一样的,所以就是导致不稳定。但是呢,在实际的使用中却是非常的多的,而且这部分的参数很重要。

这些参数大致可以分为三类:

  1. 性能参数(Performance Options):用于JVM的性能调优和内存分配控制,如初始化内存大小的设置;
  2. 行为参数(Behavioral Options):用于改变JVM的基础行为,如GC的方式和算法的选择;
  3. 调试参数(Debugging Options):用于监控、打印、输出等 JVM 参数,用于显示 JVM 更加详细的信息;
1. 性能参数
参数及其默认值描述
-XX:LargePageSizeInBytes=4m设置用于Java堆的大页面尺寸
-XX:MaxHeapFreeRatio=70GC后java堆中空闲量占的最大百分比
-XX:MinHeapFreeRatio=40GC后java堆中空闲量占的最小百分比
-XX:MaxNewSize=size新生成对象能占用内存的最大值
-XX:MaxPermSize=64m老生代对象能占用内存的最大值
-XX:NewRatio=2新生代内存容量与老生代内存容量的比例
-XX:NewSize=2.125m新生代对象生成时占用内存的默认值
-XX:ReservedCodeCacheSize=32m保留代码占用的内存容量
-XX:ThreadStackSize=512设置线程栈大小,若为0则使用系统默认值
-XX:+UseLargePages使用大页面内存
2. 行为参数

JDK 1.8 默认使用 PS+PO 收集器

参数及其默认值描述
-XX:+ScavengeBeforeFullGC新生代GC优先于Full GC执行
-XX:+UseGCOverheadLimit在抛出OOM之前限制jvm耗费在GC上的时间比例
-XX:-UseParNewGC打开此开关,使用ParNew+Serial Old收集器
-XX:-UseConcMarkSweepGC使用ParNew+CMS+Serial Old收集器对老生代采用并发标记交换算法进行GC
-XX:-UseParallelGC启用并行GC,使用ParallelScavenge+Serial Old收集器
-XX:-UseParallelOldGC对Full GC启用并行,当-XX:-UseParallelGC启用时该项自动启用,ParallelScavenge+Parallel Old收集器
-XX:-UseSerialGC启用串行GC,使用 Serial + Serial Old 收集器
-XX:SurvivorRatio=nEden区域与Survivor区域大小之比。预设值为8
-XX:PretenureSizeThreshold=n直接晋升到老年代的对象大小,设置这个参数之后,大于这个参数的对象直接进入到老年代分配
-XX:MaxTenuringThreshold=n晋升到老年代的对象年龄,每个对象在坚持过一次Minor GC之后,年龄加1,当超过这个值之后就进入老年代。预设值为15
-XX:+UseAdaptiveSizePolicy动态调整Java堆中各个区域的大小以及进入老年代的年龄
-XX:ParallelGCThreads=n设置并行收集器收集时使用的CPU数。并行收集线程数
-XX:MaxGCPauseMillis=n设置并行收集最大暂停时间
-XX:GCTimeRatio=n设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+N)
-XX:+UseThreadPriorities启用本地线程优先级
-XX:-DisableExplicitGC禁止调用System.gc();但JVM的GC仍然有效
-XX:+MaxFDLimit最大化文件描述符的数量限制
3. 调试参数
参数及其默认值描述
-XX:-CITime打印消耗在JIT编译的时间
-XX:ErrorFile=./hs_err_pid.log保存错误日志或者数据到文件中
-XX:HeapDumpPath=./java_pid.hprof指定导出堆信息时的路径或文件名
-XX:-HeapDumpOnOutOfMemoryError当首次遭遇OOM时导出此时堆中相关信息
-XX:OnError=”;\“出现致命ERROR之后运行自定义命令
-XX:OnOutOfMemoryError=”;\“当首次遭遇OOM时执行自定义命令
-XX:-PrintClassHistogram遇到Ctrl-Break后打印类实例的柱状信息,与jmap -histo功能相同
-XX:-PrintConcurrentLocks遇到Ctrl-Break后打印并发锁的相关信息,与jstack -l功能相同
-XX:-PrintCommandLineFlags打印在命令行中出现过的标记
-XX:-PrintCompilation当一个方法被编译时打印相关信息
-XX:-PrintGC每次GC时打印相关信息
-XX:-PrintGCDetails每次GC时打印详细信息
-XX:-PrintGCTimeStamps打印每次GC的时间戳
-XX:-TraceClassLoading跟踪类的加载信息
-XX:-TraceClassLoadingPreorder跟踪被引用到的所有类的加载信息
-XX:-TraceClassResolution跟踪常量池
-XX:-TraceClassUnloading跟踪类的卸载信息
-XX:-TraceLoaderConstraints跟踪类加载器约束的相关信息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值