JVM-07-监控和分析工具(命令行)

JVM-07-监控和分析工具(命令行)

前序

通过前面的几篇,我们介绍了Java虚拟机的内存分配以及内存回收等理论知识,了解这些知识对于我们在实际生产环境中提高系统的运行效率是有很大的帮助的。

但是话又说回来,在实际生产环境中,线上项目正在运行,我们怎么去监控虚拟机的运行效率呢?

又或者是线上项目发生了OOM,异常堆栈的信息,我们又怎么去抓取,然后去分析定位问题的呢?

本篇博客,我们就来介绍各种虚拟机监控和分析工具,当然都是命令行工具,不够直观,下篇博客我们会介绍各种可视化工具。

1. jps : 显示虚拟机进程

1
JVM Process Status Tools ,显示指定系统内所有的 HotSpot 虚拟机进程。

该命令有如下常用参数:

  • - l 显示应用程序main类完整包名称或应用程序的JAR文件的完整路径名
  • - v 显示虚拟机启动时的JVM参数
  • - m 显示虚拟机进程启动时传给main()函数的参数

比如,我在服务器上启动了一个Tomcat,如下:

mark

然后,输入 jps 命令,打印信息如下:

mark

这里的 Bootstrap 便是启动的 Tomcat进程。可以加上 -v 参数,显示所有传递给 JVM的参数信息。

mark

PS:jps 命令默认是没有安装的,需要进行安装,具体安装步骤可以百度,我这里就不做详细介绍了。

更多详细信息,请参考官方文档:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jps.html

2. jstat : 统计监视虚拟机信息工具

1
JVM Statistics Monitoring Tool,用于收集虚拟机各方面的运行数据。
  • jstat是用于监视虚拟机各种运行时状态信息的命令行工具。他可以显示本地或者远程虚拟机进程中的类加载,内存,垃圾手机,JIT编译等运行时数据,他是运行时期定位虚拟机性能问题的首选工具。

  • 但是终究是命令行工具,后面我们会介绍更加直观的图形化工具。

该命令监控本地的格式如下:

jstat -参数 vmid 采样间隔时间 采样次数

  1. 常用的参数如下:

mark

  1. vmid

表示目标虚拟机的标识符,在Linux系统上可以通过我们上小节介绍的jps命令,前面输出的数字便是进程PID。在Windows平台上,可以通过任务管理器查看。

  1. 采样间隔时间

默认单位是毫秒,必须是正整数。

实例1:这里我们加入 -class 参数,查看类装载信息:

mark

相关表头信息:

  • Loaded:加载的类数量
  • Bytes:加载的类字节KB大小
  • Unloaded:卸载的类数量
  • Bytes:卸载的类字节KB大小。
  • Time:执行类加载和写在操作所花费的时间

jstat的更多详细信息,

请参考官方文档:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html

3. jinfo : 实时的查看和调整虚拟机的各项参数

1
jinfo(Confiiguration Info for Java):实时的查看和调整虚拟机各项参数
  • jinfo ,通过此命令,我们可以实时的查看和调整虚拟机的各项参数(包括显示指定或默认配置的)。

该命令格式如下:jinfo [选项] pid

  • 常用选项如下
  1. 没有选项: 打印系统属性名键值对

mark

  1. -参数名称

打印指定参数名称和值

mark

  1. -flag [+|-] 参数名称

启用或者禁用指定的布尔命令。

  1. -flag name=value

设置参数name的值为value

  1. -sysprops

打印Java属性名称和键值对

  • pid命令

进程号,和上面一样,可以通过jps命令获取。

jinfo更多详细信息,

请参考官方文档:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jinfo.html

4. jmap : 内存映像工具

1
jmap(Memory Map for Java):用于生成堆存储快照

jmap主要用于获取堆内存快照文件,在生产环境中,发生OOM(堆内存溢出)异常时,我们可以通过这个快找文件来快速定位具体代码位置

这个命令还可以用来查询finalize队列,Java堆和永久代信息,如空间使用率,当前用的是哪种垃圾收集器。

该命令格式如下:

jmap [参数] pid

  • 常用参数如下

mark

  • 对于堆内存溢出异常,在前面介绍[虚拟机参数]时,我们介绍过,通过下面两个参数,也能够打印堆内存快照。
1
2
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath
  • 下面我们通过代码,演示堆内存溢出异常

未设置JVM参数OOM异常如下

mark

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package Heap;
// -Xms20M -Xmx20M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./
import java.util.ArrayList;
import java.util.List;

public class DumpHeap {

private static final int MB1 = 1024*1024;

public static void main(String[] args) {
List<Object> list = new ArrayList<>();

while (true){
list.add(new Object[MB1]);
}
}
}

-Xms20M -Xmx20M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./

设置了如上JVM参数之后,异常如下所示:

mark

生成快照文件如下: 可以用jprofiler打开

mark

这里打开可以看到哪些文件占用空间是最大的

mark

那么,怎么通过 jmap 命令来生成堆内存快照呢?

1
jmap -dump:format=b,file=heap20190821.hprof  16823

后面的数字是进程PID,可以通过jps命令来获取。

得到堆内存快照了,那么我们怎么去查看呢?

  • 在eclipse中,可以下载 MAT 工具,

  • 而在 IDEA中,可以下载 JProfiler 插件。(也就是上面图中的插件)

jmap更多详细信息,

请参考官方文档:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jmap.html

5. jstack : Java堆栈跟踪工具

1
Stack Trace for Java,用于生成虚拟机当前时刻的线程快照。
  • 线程快照其实就是当前虚拟机每一条线程正在执行的堆栈集合
  • 通过线程快照可以用来定位线程出现长时间停顿的原因(死锁,死循环,请求外部资源的长时间等待)!!!

该命令格式如下

jstack [选项] pid

  • 常用选项如下:

    mark

参考文档:https://docs.oracle.com/javase/8/docs/technotes/tools/index.html

打赏
  • 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!
  • © 2019-2022 Zhuuu
  • PV: UV:

请我喝杯咖啡吧~

支付宝
微信