JVM参数配置
标准参数
- (-)开头,所有的JVM实现都必须实现这些参数的功能,而且向后兼容标准参数比较固定不会轻易改变,JDK的版本发布对于标准参数不会产生变化
-version 输出JDK的版本信息
-help 输出JDK的帮助信息
-server/client 指定JVM的运行为server/client的运行
-cp/classpath 指定classpath路径
-DpropertyName=value 指定系统变量propertyName=value
示例:
System.getProperty("propertyName") //得到value
非标准参数(-X)
(-X)头,默认JVM实现这些参数的功能,但是并不保证所有JVM实现都满足,且不保证向后兼容
-Xms256M 设置最小堆(Heap)空间
-Xmx256M 设置最大堆(Heap)空间
-Xmn512M 设置Young区的大小
-Xss356k 设置线程栈的大小(深度)JDK5.0以后每个线程堆栈大小为1M,
以前每个线程堆栈大小为256K,应该基于应用的线程所需内存大小进行调整。
在相同物理内存下,减小这个值能生成更多的线程
非Stable参数(不稳定参数)(-XX)
(-XX)开头,此类参数各个JVM实现会有所不同,将来可能会随时取消,需要慎重使用. 所以也叫不稳定参数.
- 赋值参数 -XX:propertyName=value
-XX:MaxGCPauseMillis=500 垃圾回收器最大的停顿时间 -XX:InitialHeapSize=1000M -XX:MaxHeapSize=1000M -XX:ThreadStackSize=256K 能进行修改的参数(linux环境下) java -XX:+PrintFlagsFinal -version |grep manageable --linux
- 布尔参数 -XX:+propertyName
-XX:+UseConcMarkSweepGC 指定CMS垃圾回收器
-XX:+UseG1GC 指定G1垃圾回收器
-XX:+UseCompressedOops 开启压缩指针
-XX:+PrintFlagsFinal 打印所有的参数
查看JDK1.8中不指定的情况.默认的垃圾回收器是谁.
默认使用PS+PO的组合
前面加:=的参数是修改过的参数[jvm启动系统修改或者认为修改都是:=]
[manageable]的表示可以在程序运行期间通过jinfo进行修改的
[product]的表示不可以在程序运行期间通过jinfo进行修改的.
bool HeapDumpOnOutOfMemoryError //自动heap溢出异常保存heap快照
ccstr HeapDumpPath //heap快照保存位置
常见参数列表
参数 | 含义 | 说明 |
---|---|---|
-XX:InitialHeapSize=100M | 设置初始化堆大小 | 同-Xms100M |
-XX:MaxHeapSize=100M | 设置Heap的最大大小 | 同-Xms100M |
-XX:NewSize=20M | 设置Heap Young代的大小 | 年轻代 |
-XX:MaxNewSize=50M | 设置Heap Young最大大小 | 年轻代 |
-XX:OldSize=50M | 设置Heap Old大小 | 老年代 |
-XX:MetaspaceSize=50M | 设置Metaspace的大小 | 在1.6之前有元空间 |
-XX:MaxMetaspaceSize=50M | 设置Metaspace空间最大大小 | |
-XX:+UseParallelGC | 使用UseParallelGC | 新生代GC,吞吐量优先 |
-XX:+UseParallelOldGC | 使用UseParallelOldGC | 老年代,吞吐量优先 |
-XX:+UseConcMarkSweepGC | 使用CMS GC | 老年代,停顿时间优先 |
-XX:+UseG1GC | 使用G1GC | 新生代,老年代,停顿时间优先 |
-XX:NewRatio | 新老生代的比值 | 比如-XX:Ratio=4,则表示新生代:老年代=1:4,也就是新生代占整个堆内存的1/5 |
-XX:SurvivorRatio | 两个S区和Eden区的比值 | 比 如 - XX:SurvivorRatio=8, 也就是(S0+S1):Eden=2:8,也就是一个S占整个新生代的1/10 |
-XX:+HeapDumpOnOutOfMemoryError | 启动堆内存溢出打印 | 当JVM堆内存发生溢出时,也就是OOM,自动生成dump文件 |
-XX:HeapDumpPath=heap.hprof | 指定Heap快照打印位置 | 表示在当前目录生成一个heap.hprof文件 |
-XX:+PrintGCDetails -XX:+PrintGCTimeStamps - XX:+PrintGCDateStamps -Xloggc:g1- gc.log | 打印出GC日志 | 可以使用不同的垃圾收集器,对比查看GC 情况 |
-Xss128k | 设置每个线程的堆栈大小 | 经验值是3000-5000 最佳 |
-XX:MaxTenuringThreshold=6 | 提升年老代的最大临界值 | 默认值为 15 |
-XX:InitiatingHeapOccupancyPercent | 启动并发GC周期时堆内存使用占比 | G1之类的垃圾收集器用它来触发并发GC周期,基于整个堆的使用率,而不只是某一代内存的使用比. 值为 0 则表示”一直执行GC循环”. 默认值为 45. |
-XX:G1HeapWastePercent | 允许的浪费堆空间的占比 | 默认是10%,如果并发标记可回收的空间小于10%,则不会触发MixedGC |
-XX:MaxGCPauseMillis=100ms | G1最大停顿时间 | 暂停时间不能太小, 太小的话就会导致出现G1跟不上垃圾产生的速度。最终退化成Full GC。所以对这个参数的调优是一个持续的过程,逐步调整到最佳状态。 |
-XX:ConcGCThreads=n | 并发垃圾收集器使用的线程数量 | 默认值随JVM运行的平台不同而不同 |
-XX:+UseAdaptiveSizePolicy | 动态调整java堆中各个区域的大小以及进入老年代的年龄 | |
-XX:CompileThreshold=1000 | 表示一个方法被调用1000次之后, 会被认为是热点代码,并触发即时编译 |
优化问题排查及分析工具
jdk自带工具
- jps 罗列当前系统中运行的JVM进程
jps
不带参数,默认显示 进程ID 和 启动类的名称
jps -m
含义:参数 -m 可以输出传递给 Java 进程(main 方法)的参数。
jps -l
输出主函数的完整路径(类的全路径)
jps -v
(显示传递给 JVM 的参数)
- jinfo 主要用于打印配置信息,包括命令行参数、系统变量和主动修改部分配置信息
官网位置: https://docs.oracle.com/en/java/javase/11/tools/jinfo. html#GUID-69246B58-28C4-477D-B375-278F5F9830A5
jinfo -flag {PID}
打印{PID}对应java进程的 属性的值) 如:jinfo -flag PrintGC {PID}
jinfo -flags {PID}
打印{PID}对应java进程曾经赋值过的参数 如: jinfo -flags {PID}
jinfo -sysprops {PID}
打印所有{PID}对应Java进程的系统参数键值对
jinfo -flag [+|-] {PID} jinfo -flag = {PID}
给对应{PID}JVM进程修改对应的属性.
-XX:+PrintFlagsFinal 打印的结果中 [manageable]的可以通过jinfo进行修改
如 :jinfo -flag +HeapDumpOnOutOfMemoryError {PID} jinfo -flag HeapDumpPath=/root/jvmcamp/test.hprof
- jstat
对JVM应用程序的资源和性能进行实时的反馈的命令行工具. 其中包括了对类加载,堆内存使用情况和垃圾回收等诸多方面…
命令解释:jstat [-命令选项] {PID} [间隔时间] [查询次数]
官网:https://docs.oracle.com/en/java/javase/11/tools/jstat.html# GUID-5F72A7F9-5D5A-4486-8201-E1D1BA8ACCB5
jstat -options
获取jstat可以获取哪些信息的监控.
- -class 用于查看类加载情况的统计
- -compiler 用于查看HotSpot中即时编译器编译情况的统计
- -gc 用于查看JVM中堆的垃圾收集情况的统计
- -gccapacity 用于查看新生代、老生代及持久代的存储容量情况
- -gcmetacapacity 显示metaspace的情况
- -gcnew 用于查看新生代垃圾收集的情况
- -gcnewcapacity 用于查看新生代存储容量的情况
- -gcold 用于查看老生代及持久代垃圾收集的情况
- -gcoldcapacity 用于查看老生代的容量
- -gcutil 显示垃圾收集信息
- -gccause 显示垃圾回收的相关信息(同-gcutil),同时显示最后一次仅当前正在发生的垃圾收集的原因
- -printcompilation 输出JIT编译的方法信息
示例:
- 查看类装载信息
jstat -class {PID} 3000 20
输出{PID}JVM进程的类装载信息,每3000毫秒输出一次,共输出20次
- 查看垃圾回收的信息
jstat -gc {PID} 2000 5
输出{PID}JVM进程的GC信息,每2000毫秒输出一次,共计输出5次
- jstack
Jstack是Jdk自带的线程跟踪工具,用于获取指定JVM进程的线程堆栈信息。
我们可基于jstack获取的线程堆栈等信息去定位线程出现长时间停 顿的原因,线程间死锁、死循环、请求外部资源导致的长时间等待等等JVM性能缓慢的情况
官网: https://docs.oracle.com/en/java/javase/11/tools/jstack.html#GUID-721096FC-237B-473C-A461-DBBBB79E4F6A
用法:jstack {pid}
利用jstack排查死锁
CPU飙升排查
top 指令找到对象的进程. 如果是java进程
top -Hp {PID}找到CPU使用最高的线程pid 将此值改变为16进制
jstack {PID} | grep 16进制PID -A20
关注线程状态
RUNNABLE,线程处于执行中
BLOCKED,线程被阻塞
WAITING,线程正在等待
- jmap
jmap命令是一个可以输出JVM某一时刻运行状态的命令[内存,GC情况,对象存活情况]
查看 GC使用的算法,heap(堆)的配置及JVM堆内存的使用情况
jmap -heap {PID}
Young各个部分比例E:S1:S2为什么不是8:1:1?
Old:Young的比例好像也不是2:1
原因:是因为JVM开启了自适应调整的参数
jinfo -flag UsePSAdaptiveSurvivorSizePolicy {PID}
查看JVM中各个对象数量,大小[live]
jmap -histo:live {PID}
dump堆里的对象信息和内存信息,进行相关的分析 慎用
为什么慎用? 整个堆的dump过程中,是暂停所有执行线程的业务逻辑的.可以认为是STW的
jmap -dump:format=b,file=J://resource//andy.hprof {PID}
jmap - dump:live,format=b,file=J://resource//any.hprof {PID}
开发过程中,我们可以加上
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=heap.hprof
这两个参数在JVM程序出现堆异常时,自动dump 内存快照信息
使用MAT工具进行分析
使用在线的MAT(Memory Analyzer Tool)工具分析 https://heaphero.io/
- jhat
基于jmap dump的hprof文件,进行统计分析的非常难用的工具,对中国程序员很不友好…
jhat -port 8888 e://demo.hprof
- jconsole
是JDK自带提供的实时监测工具 了解即可,不太好用 - jvisualvm
是JDK自带提供的实时监测工具.较为好用.(推荐)- 监控本机JVM进程,直接双击打开即可…可以查看到配置信息,CPU,线程执行详情等等
- 分析内存快照 hprof文件
- 分析远程服务器的JVM进程
第三方好用工具
- arthas
arthas是阿里开源的Java实时监控和问题排查工具.它是以命令行交互的方式进行监控和排查的.
官方代码托管github https://github.com/alibaba/arthas
大家可以去其官网进行了解和使用. 常用的命令