环境准备
首先无论是window还是生产环境linux,使用Java自带的监控工具的前提是,服务器已经安装了java程序
jps [虚拟机进程监控工具]
jps: jvm process status
语法: jps [options]
进行故障排查的时候一般都会先用jps找到java程序的PID
jstack [java堆栈跟踪工具]
jstack: stack trace for java
语法: jstack option PID
示例:
如果展示的堆栈信息过多,可以将文件导出,从服务器下载下来在通过文件编辑器来分析
jstack -l 6 > /home/aaa.txt
jstat [虚拟机统计信息监控工具]
jstat: jvm statistics monitoring tool
语法: jstat option PID intervel count
option:
- -class:显示类加载情况。
- -compiler:显示JIT编译器统计信息。
- -gc:显示垃圾回收统计信息。
- -gccapacity:显示垃圾回收堆内存使用情况。
- -gcmetacapacity:显示垃圾回收非堆内存使用情况。
- -gcnew:显示新生代垃圾回收统计信息。
- -gcnewcapacity:显示新生代垃圾回收堆内存使用情况。
- -gcold:显示老年代垃圾回收统计信息。
- -gcoldcapacity:显示老年代垃圾回收堆内存使用情况。
- -gcutil:显示垃圾回收堆内存使用情况总览。
- -printcompilation:显示 JIT 编译器编译情况。
intervel: 指定采样的间隔时间默认是ms,可以使用s/ms来指定,例如:1s/100ms
count: 指定采样的次数
示例:
- -S0C:年轻代中第一个survivor(幸存区)的容量 (字节)
- -S1C:年轻代中第二个survivor(幸存区)的容量 (字节)
- -S0U:年轻代中第一个survivor(幸存区)目前已使用空间 (字节)
- -S1U:年轻代中第二个survivor(幸存区)目前已使用空间 (字节)
- -EC:年轻代中Eden(伊甸园)的容量 (字节)
- -EU:年轻代中Eden(伊甸园)目前已使用空间 (字节)
- -OC:Old代的容量 (字节)
- -OU:Old代目前已使用空间 (字节)
- -MC:metaspace(元空间)的容量 (字节)
- -MU:metaspace(元空间)目前已使用空间 (字节)
- -CCSC:当前压缩类空间的容量 (字节)
- -CCSU:当前压缩类空间目前已使用空间 (字节)
- -YGC:从应用程序启动到采样时年轻代中gc次数
- -YGCT:从应用程序启动到采样时年轻代中gc所用时间(s)
- -FGC:从应用程序启动到采样时old代(全gc)gc次数
- -FGCT:从应用程序启动到采样时old代(全gc)gc所用时间(s)
- -GCT:从应用程序启动到采样时gc用的总时间(s)
jmp [java内存映射工具]
jmp: Memory Map for Java 语法: jmap [option] PID
示例一: 查看堆信息 jmap -heap PID
示例二: 存储堆快照信息 jmap -dump:live,format=b,file=dump.bin 6
生成的快照文件可以从服务器下载下载下来,通过jVisualVM可视化工具来分析
jvisualVM [强大的多合一性能分析工具]
jvisualVM: All-in-One Java Troubleshooting Tool jvisualVM是java官方发布的最强大的运行监控和性能分析工具,甚至比一些收费的软件还要强大,个人也是十分推崇,除此之外还有一个优点就是对程序的性能影响很小,这使得它直接可以运用于生产环境。 注意jvisualVM在java8高版本后安装就不再默认自带了,需要自己去下载。
下载地址:visualvm.github.io/index.html
介绍一下IDEA安装visualvm插件的方法
step1: IDEA插件搜索VisualVM找到下图所示插件,install即可
step2: 配置jdk和visualvm路径
找到IDEA的setting》other setting 》visualvm Launcher进行如下配置。
step3:IDEA启动的时候相关图标就会点亮
step4:简单示例演示
public class JVMTest1 {
public static void main(String[] args) {
while (true){
String str = new String("abc**");**
}
}
}
点击运行即可打开visualvm界面
小插曲:打开visualvm的时候报了“Local Applications Cannot Be Detected” 错误, 看了官方问题排查visualvm.github.io/troubleshoo…
先找到所指文件位置,然后删除后在启动就好了
再次点击运行就可以找到相关PID了
记一次线上OOM问题排查
项目原先有一个需求就是希望将系统内的历史发票进行ocr识别并拆分,然后将拆分后的pdf文件绑定到发票影像件上,新的版本已经实现了对客户上传的pdf发票进行拆分了,这次主要是解决历史发票问题,统计历史发票未绑定影像件的发票大概有3000张左右,原本这是很简单的工作,后来在周六进行跑批处理的时候,发现ocr识别任务迟迟未结束,后使用top命令发现cpu居高不下,此时已经猜测可能是因为多线程处理发票文件导致的,因为发票拆分,涉及到读取磁盘pdf文件,pdf分页转图片,然后调用中台ocr识别接口,然后根据识别的发票号关联系统发票,这其中涉及大量IO密集型线程。猜测归猜测还是需要证据来验证,后使用jps找到Java程序PID,然后通过jmap导出对存储快照,将服务器dump文件下载到本地,通过本地jvisualVM进行分析,找到oom相关线程确定后确实是跑批导致的,最后发现发票pdf文件中有十几个是几百M的文件,多线程读取磁盘文件到内存后,并不能立马释放读取的文件流(因为需要进行ocr识别)导致内存溢出,后停调了跑批,将大文件的pdf先摘出,后再跑就能正常处理。