JVM分析利器
大家在学习JVM的时候知道有好多参数,另外在我们系统在出现问题的时候我们可以接触对JVM中堆使用情况和垃圾回收情况进行分析,同时在jvm调优的时候通过分析GC日志中吞吐量和停顿时间来不断优化,那么对上述指标分析我们除了有JVM的系统理论知识支撑外,还要借助比较优秀的分析利器帮助我们去分析。
JVM分析工具
1.jvm参数
1.1 -XX参数
1 | a.Boolean类型 |
1.2 其他参数
1 | -Xms1000等价于-XX:InitialHeapSize=1000 |
1.3 设置参数方式
1 | 开发工具中设置比如IDEA,eclipse |
例子
1 | (1)设置堆内存大小和参数打印 |
1.4常用参数汇总
参数 | 含义 | 说明 |
---|---|---|
-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 | 设置方法区大小 | |
-XX:MaxMetaspaceSize=50M | 方法区最大大小 | |
-XX:+UseParallelGC | 使用UseParallelGC | 新生代,吞吐量优先 |
-XX:+UseParallelOldGC | 使用UseParallelOldGC | 老年代,吞吐量优先 |
-XX:+UseConcMarkSweepGC | 使用CMS | 老年代,停顿时间优先 |
-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.hprof文件 |
XX:+PrintGCDetails - XX:+PrintGCTimeStamps - XX:+PrintGCDateStamps Xloggc:$CATALINA_HOME/logs/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=200ms | G1最大停顿时间 | 暂停时间不能太小,太小的话就会导致出现G1跟不上垃 圾产生的速度。最终退化成Full GC。所以对这个参数的 调优是一个持续的过程,逐步调整到最佳状态。 |
-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中 |
其他常用的参数:
-XX:+CMSParallelInitialMarkEnabled表示在初始标记的多线程执行,减少STW;
-XX:+CMSScavengeBeforeRemark:在重新标记之前执行minorGC减少重新标记时间;
-XX:+CMSParallelRemarkEnabled:在重新标记的时候多线程执行,降低STW;
-XX:CMSInitiatingOccupancyFraction=92和-XX:+UseCMSInitiatingOccupancyOnly配套使用,如果不设置后者,jvm第一次会采用92%但是后续jvm会根据运行时采集的数据来进行GC周期,如果设置后者则jvm每次都会在92%的时候进行gc;
-XX:+PrintHeapAtGC:在每次GC前都要GC堆的概况输出
2.常用命令
2.1jps
查看java进程
2.2 info
实时查看jvm参数
1 | jinfo -flag name PID 查看某个java进程的name属性的值 |
实时修改参数
参数只有被标记为manageable的flags可以被实时修改
1 | jinfo -flag [+|-] PID |
2.3 jstat
查看虚拟机性能的统计信息「使用jstat摸清线上系统的JVM运行状况」
1 | 查看类装载信息 |
1 | jstat -gc PID |
2.4 jstack
jstack能生成JVM当前时刻的线程快照,以此来定位线程出现长时间停顿的原因,最常见应用场景为:
- 查看线程间死锁
- 分析CPU过高原因
查看线程堆栈信息命令
1 | jstack [-option] <pid> |
指令 | 说明 |
---|---|
-F | 当jstack指令无响应时,强制打印一个堆栈信息 |
-m | 打印包含Java和C/C++帧的混合模式堆栈跟踪 |
-l | 打印关于锁的其他信息,比如拥有java.util.concurrent ownable同步器的列表 |
-h / -help | 打印帮助信息 |
cpu 100%了定位如下方法:
1 | top -c . 输入P按照cpu使用率排序 |
2.5 jmap
查看打印及dump出堆内存转储快照信息
1 | 项目启动参数设置 |
3.常用工具
3.1 jconsole
JDK自带的可视化监控工具
可以查看java应用程序运行概况,监控堆信息,永久区的使用
3.2 jvisualvm
可以i监控本地和远端java进程的cpu,类线程等
远程连接服务器监控远端java进程,需要在远端程序上配置
加入要分析远程java进程,以阿里云服务器tomcat为例子
1.需要修改tomcat中 bin/catalina.sh 这个文件
1 | JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote - |
2.在 ../conf 文件中添加两个文件jmxremote.access和jmxremote.password
jmxremote.access 文件
1 | guest readonly |
jmxremote.password 文件
1 | guest guest |
1 | 授予权限 : chmod 600 *jmxremot* |
3.将连接服务器地址改为公网ip地址
1 | hostname -i 查看输出情况 |
4.启动tomcat
5.查看tomcat启动日志及端口监听
1 | tail -f ../logs/catalina.out |
6.查看8998监听情况,可以发现多开了几个端口
1 | lsof -i:8998 得到PID |
3.3jmc工具
3.4 阿里arthas
github :https://github.com/alibaba/arthas
Arthas 是Alibaba开源的Java诊断工具,采用命令行交互模式,是排查jvm相关问题的利器
1 | 下载安装: |
常用命令
1 | version:查看arthas版本号 |
4.分析堆内存
4.1MAT工具
Java堆分析器,用于查找内存泄漏
Heap Dump,称为堆转储文件,是Java进程在某个时间内的快照
下载地址 :https://www.eclipse.org/mat/downloads.php
获取dump文件
1 | 手动dump |
4.2 perfma在线工具
5 GC日志分析工具
获取GC日志
1 | -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps |
5.1 在线
1 | http://gceasy.io |
5.2 GCViewer
分析GC日志的工具:
1.GCHisto http://java.net/projects/gchisto
直接点击gchisto.jar就可以运行,点add载入gc.log
统计了总共gc次数,youngGC次数,FullGC次数,次数的百分比,GC消耗的时间,百分比,平均消耗时间,消耗时间最小最大值等
2.GCLogViewer http://code.google.com/p/gclogviewer/
点击run.bat运行
整个过程gc情况的趋势图,还显示了gc类型,吞吐量,平均gc频率,内存变化趋势等
Tools里还能比较不同gc日志
6 jvm参数配置模版
如何在JVM内存溢出OOM时候自动dump内存快照?
设置JVM参数:
-XX:+HeapDumpOnOutOfMemoryError
-XX:+HeapDumpPath=/usr/local/app/oom
jvm参数中加入打印GC日志
-XX:+PrintGCDetails 打印详细的GC日志
-XX:+PrintGCTimeStamps 打印出来每次GC发生的事件
-Xloggc:gc.log 这个参数可以设置将gc日志写入一个磁盘文件
下面总结一下JVM参数模板:
1 | -Xms4096M -Xmx4096M -Xmn3072M -Xss1M -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFaction=92 -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=0 -XX:+CMSParallelInitialMarkEnabled -XX:+CMSScavengeBeforeRemark -XX:+DisableExplicitGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:gc.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/usr/local/app/oom |