-
VisualVM工具
-
插件使用和下载
-
分析dump文件
-
其他工具
-
总结
===============================================================
JVM系列前5篇文章相对偏向于理论,从这篇开始将会结合实际场景进行分析以及如何对JVM进行调优。
==================================================================
所谓的JVM调优说白了就是去设置一个合理的,适合当前系统的JVM所提供的参数。从总体上来说JVM参数可以分为三大类:标准参数,-X参数,-XX参数。
以“-”开头的参数称之为标准参数,标准参数是任何一个JDK版本都支持的参数,比较稳定,一般不会随着jdk版本的变化而变化。
比如:
-version
-help
-server
-cp
以-X开头的参数是在特定版本HotSpot支持的命令,jdk版本变化之后,参数可能会发生变化。这个参数用的比较少。如以下几种:
-Xint 解释执行
-Xcomp 第一次使用就编译成本地代码
-Xmixed 混合模式,JVM自己来决定
这种参数用的比较少,了解就可以了,在这里不做演示
-XX是一种不稳定的参数,下一个版本可能会取消。-XX是JVM调优时的主要参数。
-XX参数分为Boolean型和非Boolean型。
Boolean型
Boolean类型的-XX参数使用格式为:
-XX:[±] +或-表示启用或者禁用name属性
如:
-XX:+UseConcMarkSweepGC 表示启用CMS类型的垃圾回收器
-XX:+UseG1GC 表示启用G1类型的垃圾回收器
-XX:+PrintFlagsFinal 表示打印出所有的JVM参数信息
打印所有JVM参数
我们用-XX:+PrintFlagsFinal去打印一下所有的参数出来看一下:
任意新建一个Java类:
package com.zwx.jvm;
public class TestJVMParam {
public static void main(String[] args) {
System.out.println(11);
}
}
本人用的是IntelliJ IDEA工具,选择:Run–>Edit Configurations,然后点击左边的+号,选择Application,出现如下所示界面,加入JVM参数:
然后运行main方法,就会打印出所有参数(有700多个):
注意:上图中打印出来的参数中“=”表示默认值,“:=”表示被用户或JVM修改后的值
非Boolean型
非Boolean类型的-XX参数的使用格式为:
-XX= name表示属性,value表示属性对应的值
如:
-XX:MaxMetaspaceSize=5M 设置最大永久代空间大小(jdk1.8)
还有其他一些我们非常常用的参数,比如:-Xms,-Xmx,-Xss,但是实际上这几种参数也是属于-XX参数,这几种写法不过就是一种为了方便而设置的简写形式。所以在上面打印出来的参数中搜索-Xms,-Xmx,-Xss是搜索不到的。
-Xms1000等价于-XX:InitialHeapSize=1000
-Xmx1000等价于-XX:MaxHeapSize=1000
-Xss100等价于-XX:ThreadStackSize=100
| 参数 | 含义 | 说明 |
| — | — | — |
| -XX:CICompilerCount=3 | 最大并行编译数 | 大于1时可以提高编译速度,但会影响系统稳定性,增加JVM崩溃的可能 |
| -XX:InitialHeapSize=100M | 初始化堆大小 | 简写-Xms100M |
| -XX:MaxHeapSize=100M | 最大堆大小 | 简写-Xmx100M |
| -XX:NewSize=20M | 设置年轻代的大小 | - |
| -XX:MaxNewSize=50M | 年轻代最大大小 | - |
| -XX:OldSize=50M | 设置老年代大小 | - |
| -XX:MetaspaceSize=50M | 设置方法区大小 | jdk1.8中才有,利用元空间实现方法区 |
| -XX:MaxMetaspaceSize=50M | 方法区最大大小 | jdk1.8中才有,利用元空间实现方法区 |
| -XX:+UseParNewGC | 设置ParNe为新生代收集器 | 默认会选择Serial old作为老年代收集器和其配合 |
| -XX:+UseParallelGC | 设置Parallel Scavenge为新生代收集器,系统默认会选择Parallel Old为老年代垃圾收集器 | 这个组合是jdk1.8中默认组合,吞吐量优先的垃圾收集器 |
| -XX:+UseParallelOldGC | 设置Parallel Old为老年代垃圾收集器,系统默认会选择Parallel Scavenge为新生代垃圾收集器 | - |
| -XX:+ParallelGCThreads | 设置并行收集垃圾的线程数 | 一般设置为和cpu个数相同,这个参数也适用于CMS收集器 |
| -XX:+UseConcMarkSweepGC | 选择CMS为老年代收集器,同时系统默认会选择ParNew为新生代收集器 | 如果CMS收集器出现了Concurrent Mode Failure,则会切换到Serial Old为老年代收集器 |
| -XX:+CMSScavengeBeforeRemark | CMS收集器在最终标记前发生一次Young GC | - |
| -XX:CMSMaxAbortablePrecleanTime | CMS收集器的可中断预清理阶段最长停留时间 | 默认是5000,单位是毫秒 |
| -XX:+UseG1GC | 使用G1作为收集器 | 同时适用于新生代和老年代,是一款停顿时间优先的垃圾收集器,jdk1.9中默认垃圾收集器 |
| -XX:NewRatio | 新老生代的比值 | 比如-XX:Ratio=4,则表示新生代:老年代=1:4 |
| -XX:SurvivorRatio | 两个S区和Eden区的比值 | 比如-XX:SurvivorRatio=8,也就是(S0+S1):Eden=2:8 |
| -XX:+HeapDumpOnOutOfMemoryError | 启动堆内存溢出打印 | 当JVM堆内存发生溢出时,也就是OOM,自动生成dump文件 |
| -XX:HeapDumpPath=heap.hprof | 指定堆内存溢出打印目录 | 表示在当前目录生成一个heap.hprof文件 |
| -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:$CATALINA_HOME/logs/gc.log | 打印出GC日志 | 不同的垃圾收集器总体格式相同,但是会有小差别,G1相比较其他收集器,差别较大 |
| -Xss128k | 设置每个线程的堆栈大小 | 经验值是3000-5000最佳 |
| -XX:MaxTenuringThreshold=6 | 新生代对象进入年老代的最大临界值 | 默认15 |
| -XX:InitiatingHeapOccupancyPercent | 启动并发GC周期时堆内存使用占比 | G1之类的垃圾收集器用它来触发并发GC周期,基于整个堆的使用率,而不只是某一代内存的使用比. 值为 0 则表示”一直执行GC循环”. 默认值为 45 |
| -XX:G1HeapWastePercent | 允许的浪费堆空间的占比 | 用于G1垃圾收集器。默认是10%,如果并发标记可回收的空间小于10%,则不会触发MixedGC |
| -XX:ConcGCThreads=n | 并发垃圾收集器使用的线程数量 | 默认值随JVM运行的平台不同而不同 |
| -XX:G1MixedGCLiveThresholdPercent=65 | 混合垃圾回收周期中要包括的旧区域设置占用率阈值 | 默认占用率为 65% |
| -XX:G1MixedGCCountTarget=8 | 设置标记周期完成后,对存活数据上限为G1MixedGCLIveThresholdPercent的旧区域执行混合垃圾回收的目标次数 | 默认8次混合垃圾回收,混合回收的目标是要控制在此目标次数以内 |
| -XX:G1OldCSetRegionThresholdPercent=1 | 描述Mixed GC时,Old Region被加入到CSet中 | 默认情况下,G1只把10%的Old Region加入到CSet中 |
=====================================================================
jdk中的bin目录下提供了许多功能强大的工具可以帮助我们监控虚拟机的使用情况,掌握了这些常用工具的使用可以帮助我们更快更直观的分析问题。
工具和参数都是在不断使用的过程中掌握的,并不需要一下子就全部看完,可以大致浏览有个印象,建议大家可以收藏本篇文章,后续需要用到的时候方便查看
以下的演示均是基于linux环境下jdk1.8版本进行演示,不能环境和版本可能会有较大差异。
Java™ SE Runtime Environment (build 1.8.0_151-b12)
jps:JVM Process Status Tool,一款用于查看java进程的工具。这款工具的功能非常简单,就是查看当前环境下运行的java服务的进程id和名称,一般其他命令使用前都会先使用jps命令获取java进程信息。
如下图所示:
jps参数主要有如下选项:
| 选项 | 说明 |
| — | — |
| -q | 只输出进程id |
| -m | 输出虚拟机启动时传递给main()方法的参数 |
| -l | 输出主类的全名,如果进行执行的是jar包,则输出jar包路径 |
| -v | 输出启动虚拟机的参数 |
jstat:JVM Statistics Monitoring,一款用于监视虚拟机各种运行状态统计信息工具。主要可以显示如下信息:虚拟机进程的类装载、内存、垃圾收集、JIT编译等运行数据信息。
查看类装载信息
jstat -class PID 1000 10 //查看某个java进程的类装载信息,每1000毫秒输出一次,共输出10次
查看垃圾收集信息
jstat -gc PID 1000 10
上图中就显示个各个区以及垃圾回收的情况,具体代表含义如下:
注意:C表示Capacity(容量),U表示Used(已使用大小)
-
1、S0C、S1C表示的是Survive区的S0和S1大小(Capacity)
-
2、S1U、S2U表示已使用空间大小(Used)
-
3、EC、EU分别表示Eden区总容量和已使用容量大小
-
4、OC、OU分别表示老年代总空间大小和已使用大小
-
5、MC、MU:表示方法区(jdk1.8中通过Metaspace实现)的总空间大小和已使用大小
-
6、CCSC、CCSU:表示压缩类空间总大小和已使用大小
-
7、YGC、YGT:新生代GC次数和GC总耗时
-
8、FGC、FGCT:Full GC次数和Full GC总耗时
-
9、GCT:GC总消耗时间
如果对上面含义中涉及到的各种分区不了解的,可以点击这里详细了解。
jstat参数常用选项
| 参数 | 说明 |
| — | — |
| -class | 查看类加载/卸载数量和大小,以及所耗费的时间 |
| -gc | 统计堆内各个分区的总大小及已使用大小,以及不同分区的次数和耗时等信息 |
| -gccapacity | 同-gc相似,但是主要统计Java堆各个区域使用到的最大和最小空间 |
| -gcutil | 同-gc类似,但是主要统计已使用空间占总空间的大小 |
| -gccause | 同-gcutil一样,只是会额外输出上一次发生GC原因 |
| -gcnew | 统计新生代的GC情况 |
| -gcnewcapacity | 同-gcnew类似,但是主要统计使用到的最大和最小空间 |
| -gcold | 统计老年代的GC情况 |
| -gcoldcapacity | 同-gcold类似,但是主要统计使用到的最大和最小空间 |
| -gcpermcapaticy | 统计永久代使用到的最大和最小空间 |
| -compiler | 输出JIT编译器编译过得方法和耗时等信息 |
| -printcompilation | 输出已经被JIT编译的方法 |
jstack:Stack Trace for Java,一款用于生成当前时刻的线程状态信息的快照工具。这个对于用来分析当前线程状态时非常有用的,比如说是否有哪个线程阻塞了,或者说是否发生死锁等信息。
如:
jstack PID
可以清晰的看到当前线程的状态。另外线程的名字也会打印出来,所以在我们自己创建线程的时候建议是采用自定义的名称,这样如果有异常我们可以很容易的知道是哪个线程出了问题。
jstack参数常用选项
| 参数 | 说明 |
| — | — |
| -F | 当正常请求不被响应时,强制输出线程堆栈 |
| -l | 除堆栈外,显示关于锁的附加信息 |
| -m | 当调用本地方法时,可以显示C/C++的堆栈 |
最后
分布式技术专题+面试解析+相关的手写和学习的笔记pdf
还有更多Java笔记分享如下:
71932850.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3p3eDkwMDEwMg==,size_16,color_FFFFFF,t_70#pic_center)
可以清晰的看到当前线程的状态。另外线程的名字也会打印出来,所以在我们自己创建线程的时候建议是采用自定义的名称,这样如果有异常我们可以很容易的知道是哪个线程出了问题。
jstack参数常用选项
| 参数 | 说明 |
| — | — |
| -F | 当正常请求不被响应时,强制输出线程堆栈 |
| -l | 除堆栈外,显示关于锁的附加信息 |
| -m | 当调用本地方法时,可以显示C/C++的堆栈 |
最后
分布式技术专题+面试解析+相关的手写和学习的笔记pdf
还有更多Java笔记分享如下:
[外链图片转存中…(img-rsZjTzHk-1714513626244)]