作者 | Silently9527   责编 | 欧阳姝黎

前言

前几天中午正在和同事最近聊股市较好,这几天每天都可以喝点肉汤,心里还是挺高兴的;正在这个时候收到了线上告警邮件和运维同学的消息,“你们有服务挂了!”,心里一紧,立马打开电脑看来下线上cat监控大盘,发现很多服务都在报错,根据cat上的监控日志很快发现了其中一个服务内存溢出导致其他调用服务也有问题,竟然已经定位到了出问题的服务,那就简单了,没有是重启解决不了的问题,重启之后很快服务都恢复正常了。几分钟之后又报错了,同样也是这个服务内存溢出,经过排查后发现该服务的堆内存被改小了,好家伙,运维同学不讲武德,搞偷袭,趁我没反应过来调了内存,内存调整回去之后服务就恢复了正常。

事后把线上的快照文件拖了下来分析,发现本身这个项目的代码也有些问题,本文就整理了一下JVM常用的分析工具。

命令行工具

在安装完JDK之后在JAVA_HOME/bin目录下JDK已经提供了很多命令行的工具

可能我们最常用的就是java、javac这两个命令,除了这两个命令之外还有提供很多其他的实用工具,本文主要来一起学习对JVM监控诊断工具

虚拟机进程状况工具(jps)

该工具的功能比较单一,与linux中的ps功能类似,用来列出正在运行的虚拟机进程,并显示出运行的主类和进程号

命令格式:jps [option] [hostid]

如果需要查看远程机器的jvm进程需要填写hostid,并且需要使用RMI,比如:rmi://192.168.2.128:12345

常用的选项:

  • -q : 只显示出虚拟机的进程id(lvmid),省略主类名

  • -m : 输出启动时传递给主类的参数

  • -l : 显示出主类的全名,包括jar包路径

  • -v : 输出虚拟机进程启动时的JVM参数

虚拟机统计信息监控工具(jstat)

用于监控虚拟机运行状态信息的命令行工具,可以提供内存,垃圾收集等运行时的数据

命令格式:jstat [option vmid] [interval [s|ms] [count]]

interval表示间隔多久时间查询一次,count表示查询多少次,比如:每个两秒查询一次进程52412的垃圾收集情况,共查询5次

jstat -gc 52412 2s 5

常用的选项:

  • -class: 监控类装载,卸载次数和总空间以及加载类的耗时

  • -gc: 监控java堆的情况

  • -gcutil: 主要输出各个空间使用的百分比

  • -gcnew: 主要是监控新生代的GC状况

  • -gcold: 监控老年代的GC状况

  • -compiler: 输出JIT编译器编译过的方法和耗时信息

查看堆空间的使用百分比: jstat -gcutil 52412 2s 5

java配置信息工具(jinfo)

可以通过jinfo实时的查看和调整虚拟机的各项参数;可以通过jps -v查看虚拟机启动时候指定的参数信息,如果需要查看未显示指定的参数默认值也可以通过jinfo -flag

jinfo -flag CMSInitiatingOccupancyFraction 52412

jinfo除了可以查看参数以外,还可以在运行时修改一些允许被修改的参数

Java内存映像工具(jmap)

jmap用于生成JVM堆的快照文件,除了使用jmap工具,我们通常也会在配置JVM的启动参数-XX:+HeapDumpOnOutOfMemoryError 让JVM在发送内存溢出之后自动生成dump文件。

命令格式:jmap [option] vmid

比如生成java堆的快照文件

jmap -dump:live,format=b,file=/Users/huaan9527/Desktop/heap.hprof 59950

常用的选项:

  • -F: 当虚拟机对-dump选项没有响应时可用选择使用这个参数强制生成快照

  • -histo: 显示出堆中对象统计信息。

堆栈跟踪工具(jstack)

用于生成JVM当前线程的快照信息。通常用于查询什么原因导致线程长时间的停顿,比如:线程死循环,死锁,等待网络/IO

命令格式:jstack [option] vmid

常用的选项:

  • -F: 当请求不被响应时强制输出

  • -l:除了显示堆栈外,还需要显示锁的信息

  • -m: 如果调用到本地方法,显示出C/C++的堆栈

VisualVM 可视化工具

VisualVM是目前JDK自带的功能最强的运行监视和故障处理程序,在VisualVM之前,JDK也提供了一款可视化工具JConsole,由于JConsole的所有功能在VisualVM都有,所以可视化工具大家几乎都选择使用VisualVM。

VisualVM本身是基于Netbean开发的,所以具备了插件扩展功能,安装插件之后上面介绍的所有命令行的工具的功能都可以在VisualVM中使用。可以在在JAVA_HOME/bin目录下执行jvisualvm启动。

  • 插件安装 默认情况VisualVM提供的功能很少,需要我们在菜单栏->工具->插件里面安装插件,我这是全部插件都安装了

  • 应用程序、概述、监视

功能演示

显示出当前本机所有的JVM进程,这里显示的内容和前面说的命令行jps显示的内容一样

当前虚拟机启动信息的展示,比如:JVM启动参数、系统参数

这个页面相当于命令jstat的功能,显示出了CPU, 内存,线程,类装载当前处于什么情况

生成dump文件可以在应用程序窗口右键菜单中选择,也可以在这个页面点击右上角的堆dump

  • Visual GC 此页主要展示了GC相关的信息,这是在性能调优时常用的页面之一

我们可以写个程序来观看下这个截图各个内存区域的变化情况,为了让图的效果明显需要修改JVM的启动参数

-Xmx100m -Xms100m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/Users/huaan9527/Desktop
public static void main(String[] args) {List<DataTest> datas = new ArrayList<>();IntStream.range(0, 10000).forEach(index -> {datas.add(new DataTest());try {Thread.sleep(50);} catch (InterruptedException e) {e.printStackTrace();}});System.gc();
}static class DataTest {byte[] bytes = new byte[1024];
}

  • 线程 本页的功能相当于命令行工具jstack,主要是用于检查什么原因导致线程长时间等待,我们写程序来演示下等待外部资源、锁等待、死循环这几种请求

「等待外部资源」

public static void main(String[] args) throws IOException {BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));System.out.println(reader.readLine());try {Thread.sleep(1000000);} catch (InterruptedException e) {e.printStackTrace();}
}

选中main线程,右侧会看到当前线程运行到了readBytes,等待键盘输入

当我们在控制台输入之后再次查看main线程的状态,此时进入了TIME_WAIT状态

「锁等待」

public static void main(String[] args) throws IOException, InterruptedException {Thread thread = createLockThread(new Object());thread.join();
}public static Thread createLockThread(final Object lock) {Thread lockThread = new Thread(() -> {synchronized (lock) {try {lock.wait();} catch (InterruptedException e) {e.printStackTrace();}}}, "lockThread");lockThread.start();return lockThread;
}

lockThread线程在等待lock对象的notify方法被调用,此时处于WAITING状态,在被唤醒之前是不会再分配执行时间

「死循环」

public static void main(String[] args) throws IOException, InterruptedException {while (true) ;
}

线程一直处于运行状态,从堆栈追踪里可以看出代码一直停留在了191行,在空循环上用尽分配的执行时间

总结

本篇介绍了命令行工具和可视化工具,写到最后文中或许会存在或多或少的不足、错误之处,有建议或者意见也非常欢迎大家给我留言。

预约《大咖来了》直播,赢纪念版卫衣以及保温杯等礼品,在直播间精选留言提问题,若问题被采纳,将直接赠送马克杯!先到先得!

☞130 行代码模仿火爆抖音的“蚂蚁呀嘿”特效,你学会了吗?☞被“钱”困住的开源开发者们!
☞欧洲云计算巨头机房起火,数据中心成灰烬!Rust 游戏玩家:我白玩了
☞在内存只有24KB的电脑上写操作系统,是怎样的体验?

这几款 JVM 故障诊断处理工具,你还不会?相关推荐

  1. 「JVM 故障诊断」命令行工具

    给定一个系统问题,知识.经验是关键基础,数据(异常堆栈.JVM 运行日志.GC 日志.线程快照 threaddump/javacore.堆转储快照 heap dump/hprof 等)是依据,工具是运 ...

  2. 利用 Java dump 进行 JVM 故障诊断

    引言 对于大型 java 应用程序来说,再精细的测试都难以堵住所有的漏洞,即便我们在测试阶段进行了大量卓有成效的工作,很多问题还是会在生产环境下暴露出来,并且很难在测试环境中进行重现.JVM 能够记录 ...

  3. Jvm 系列(七):Jvm 调优-工具篇

    工具做为图形化界面来展示更能直观的发现问题,另一方面一些耗费性能的分析(dump文件分析)一般也不会在生产直接分析,往往dump下来的文件达1G左右,人工分析效率较低,因此利用工具来分析jvm相关问题 ...

  4. jvm系列(七):jvm调优-工具篇

    16年的时候花了一些时间整理了一些关于jvm的介绍文章,到现在回顾起来还是一些还没有补充全面,其中就包括如何利用工具来监控调优前后的性能变化.工具做为图形化界面来展示更能直观的发现问题,另一方面一些耗 ...

  5. 常见的几款JVM监控工具

    本文来说下常见的几款JVM监控工具 文章目录 概述 jps:查看正在运行的Java进程 jstack:打印线程快照 jmap:导出堆内存映像文件 jstat:查看jvm统计信息 jinfo:实时查看和 ...

  6. 【读书笔记】实战JAVA虚拟机JVM故障诊断与性能优化 读书笔记

    文章目录 1.概述 1.1 **第一章:初探java虚拟机** 1.2 认识java虚拟机的基本结构 1.3 常用Java虚拟机参数 1.4 垃圾回收器 1.5 垃圾收集器以及内存分配 1.6 性能监 ...

  7. 实战java虚拟机 百度云_《实战JAVA虚拟机 JVM故障诊断与性能优化》pdf百度云下载...

    内容简介· · · · · · 随着越来越多的第三方语言(Groovy.Scala.JRuby等)在Java虚拟机上运行,Java也俨然成为了一个充满活力的生态圈.<实战Java虚拟机--JVM ...

  8. jvm crash分析工具

    为什么80%的码农都做不了架构师?>>>    介绍一款非常好用的jvm crash分析工具,当jvm挂掉时,会产生hs_err_pid.log.里面记录了jvm当时的运行状态以及错 ...

  9. 「JVM 故障诊断」故障分析与处理案例

    面对线上故障,除了要了解 JVM 相关知识和工具,经验同样是很重要的: 通过设计和开发阶段先行避免问题: 在应用部署层面去解决问题: 通过升级硬件和 JDK 版本(使用新技术)解决问题: 文章目录 1 ...

最新文章

  1. html5--6-59 其他常用CSS属性
  2. JDK的安装与环境变量配置
  3. Web前端就业薪资是多少?Web前端要学什么?
  4. css 如何让背景图片拉伸填充避免重复显示
  5. SQL*Plus命令
  6. swagger OAuth认证
  7. CSS background-position用法
  8. 02~ 一步一步教你使用 SVN之SVN 的介绍
  9. LTE系统各种指标概念(EVM,ACLR)
  10. 路由器网络性能测试软件,路由器压力测试工具 路由器UDP攻击软件 路由器性能测试...
  11. 泛微协同商务系统_泛微ecology OA Beanshell组件远程代码执行漏洞复现
  12. MPEG-7描述子(0)——颜色空间
  13. zabbix-邮箱报警与微信报警
  14. python实现自动化查谁没交作业
  15. 3 个简单的技巧让你的 vue.js 代码更优雅!
  16. 聊城市普通话水平测试软件音频,聊城市普通话水平测试培训-聊城市教师教育网.ppt...
  17. 【动态规划DP,二维动归】poj1651,Multiplication Puzzle
  18. java动态编程解决分硬币问题,动态编程硬币更改问题
  19. 1.23 lseek函数
  20. 仿B站web,APP,后台

热门文章

  1. 线程池的参数及执行顺序
  2. Python:获取代码运行时间方法
  3. div超出部分点点显示
  4. 跟着大彬读源码 - Redis 1 - 启动服务,程序都干了什么?
  5. 点击startup.bat启动tomcat出现乱码
  6. 合理使用webpack提高开发效率
  7. 打印机驱动冲突和端口异常:win10更新部分补丁后,打印机本地连接(连接打印机的主机)可以打印,其他共享网络中的电脑可以连接到打印机,但不能打印——解决方案...
  8. 对自定义UITableViewCell的理解
  9. 安装Logstash
  10. PAT乙级 1032 挖掘机技术哪家强 (20 分)