Java之JVM监控工具分享

JVM的基本知识常用的也就是类加载机制内存区域、分配、OOMGCJVM参数调优

几个链接自己看:

今天结合代码讲一讲常用的java自带工具讲解,这些命令一般都是jdk/lib/tools.jar中。用来监控诊断我们的Java环境。

官方说明: https://docs.oracle.com/en/java/javase/11/tools/

1. jps

显示当前用户的所有java进程的PID 以及主类名

jps              : 显示当前用户的所有java进程的PID 以及主类名
jps -v : 打印传递给 Java 虚拟机的参数(如-XX:+UnlockExperimentalVMOptions -XX:+UseZGC)
jps -m : 打印传递给主类的参数
jps -l : 打印模块名以及包名

默认开启(UsePerfData),若加上-XX:-UsePerfData 则无法找到进程。

2. jstack

功能 jstack不仅会打印线程的栈轨迹、线程状态(BLOCKED)、持有的锁(locked…)以及正在请求的锁(waiting to lock …),而且还会分析出具体的死锁

jstack pid       : 查看线程情况
jstack -F pid : 正常输出不被响应时,使用该指令
jstack -l pid : 除堆栈外,显示关于锁的附件信息

3. jstat

功能 允许用户查看目标 Java 进程的类加载、即时编译以及垃圾回收相关的信息。它常用于检测垃圾回收GC问题以及内存泄漏问题。

显示进程中的类装载、内存、垃圾收集、JIT编译等运行数据。

常用指令

jstat -class pid              : 打印类装载、类卸载、总空间以及所消耗的时间
jstat -compiler pid : 打印即时编译相关的数据
jstat -printcompilation pid : 打印即时编译相关的数据
jstat -gc pid 1s 20 : 查询垃圾收集情况,每1秒查询一次,一共查询20次。
jstat -gccause pid : 额外输出上次GC原因
...剩下的都是以-gc为前缀的子命令,它们将打印垃圾回收相关的数据。
加上 -t参数 每行数据之前打印目标 Java 进程的启动时间

我们可以看到,这两个 Survivor 区的容量相等,而且始终有一个 Survivor 区的内存使用量为 0。

在这种情况下,Java 虚拟机会将这块内存区域回收,并标记为可分配的状态。这样子做的结果是,堆中可能完全没有 Survivor 内存区域,因而相应的 S1C 和 S1U 将会是 0。

我们可以比较 Java 进程的启动时间以及总 GC 时间(GCT 列),或者两次测量的间隔时间以及总GC时间的增量,来得出 GC 时间占运行时间的比例。

如果该比例超过 20%,则说明目前堆的压力较大;如果该比例超过 90%,则说明堆里几乎没有可用空间,随时都可能抛出 OOM 异常。

jstat还可以用来判断是否出现内存泄漏。在长时间运行的 Java 程序中,我们可以运行jstat命令连续获取多行性能数据,并取这几行数据中 OU 列(即已占用的老年代内存)的最小值。

然后,我们每隔一段较长的时间重复一次上述操作,来获得多组 OU 最小值。如果这些值呈上涨趋势,则说明该 Java 程序的老年代内存已使用量在不断上涨,这意味着无法回收的对象在不断增加,因此很有可能存在内存泄漏。

CGC 和 CGCT,它们分别代表并发 GC Stop-The-World 的次数和时间。

S0C:年轻代中第一个survivor(幸存区)的容量 (kb)
S1C:年轻代中第二个survivor(幸存区)的容量 (kb)
S0U:年轻代中第一个survivor(幸存区)目前已使用空间 (kb)
S1U:年轻代中第二个survivor(幸存区)目前已使用空间 (kb)
EC:年轻代中Eden(伊甸园)的容量 (kb)
EU:年轻代中Eden(伊甸园)目前已使用空间 (kb)
OC:老年代的容量 (kb)
OU:老年代目前已使用空间 (kb)
MC:元空间的容量 (kb)
MU:元空间目前已使用空间 (kb)
CCSC:压缩类的容量 (kb)
CCSU:压缩类目前已使用空间 (kb)
YGC:年轻代垃圾回收次数
YGCT:年轻代垃圾回收消耗时间
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间

4. jmap

功能 生成堆转储快照(heapdump) 用户统计目标 Java 进程的堆中存放的 Java 对象,并将它们导出成二进制文件。查询Java堆和永久代的详细信息,使用率,使用大小,查询finalize执行队列的信息

常用指令

jmap -heap  pid                     : 打印jvm heap的情况
jmap -histo pid : 打印jvm heap的直方图。其输出信息包括类名,对象数量,对象占用大小。 并按照内存使用量从多至少的顺序排列
jmap -histo:live pid : JVM会先触发gc,然后再统计信息,只统计堆中的存活对象的情况
jmap -dump:format=b,file=map.log pid: 将内存使用的详细情况输出到文件,之后一般使用其他工具进行分析。同样,-dump:live只保存堆中的存活对象。
jmap -clstats pid : 打印被加载类的信息
jmap -finalizerinfo pid : 该子命令将打印所有待 finalize 的对象。
jmap -permstat pid : 打印permanent generation heap情况

我们通常会利用jmap -dump:live,format=b,file=filename.bin命令,将堆中所有存活对象导出至一个文件之中。

这里format=b将使jmap导出与hprof(在 Java 9 中已被移除)、-XX:+HeapDumpAfterFullGC、-XX:+HeapDumpOnOutOfMemoryError格式一致的文件。这种格式的文件可以被其他 GUI 工具查看。

jmap(以及jinfo、jstack和jcmd)依赖于 Java 虚拟机的Attach API,因此只能监控本地 Java 进程。

一旦开启 Java 虚拟机参数DisableAttachMechanism(即使用参数-XX:+DisableAttachMechanism),基于 Attach API 的命令将无法执行。反过来说,如果你不想被其他进程监控,那么你需要开启该参数。

5. jhat

功能 一般与jmap搭配使用,用来分析jmap生成的堆转储文件。

由于有很多可视化工具(Eclipse Memory Analyzer 、IBM HeapAnalyzer)可以替代,所以很少用。不过在没有可视化工具的机器上也是可用的。

常用指令

jmap -dump:format=b,file=map.log pid   : 将内存使用的详细情况输出到文件
jhat map.log : 解析Java堆转储文件,并启动一个 web server

演示:https://www.cnblogs.com/baihuitestsoftware/articles/6406271.html

6. jinfo

功能 打印目标 Java 进程的配置参数

实时查看和调整虚拟机参数,可以显示未被显示指定的参数的默认值(jps -v 则不能)。

jinfo pid :可用来查看目标 Java 进程的参数,如传递给 Java 虚拟机的-X(即输出中的 jvm_args)、-XX参数(即输出中的 VM Flags),以及可在 Java 层面通过System.getProperty获取的-D参数(即输出中的 System Properties)。

7. jcmd

可以用来实现前面除了jstat之外所有命令的功能。

详见 :https://www.jianshu.com/p/388e35d8a09b

8. javap

javap 是一个能够将 class 文件反汇编成人类可读格式的工具。 ASM字节码操作:https://blog.csdn.net/ohcezzz/article/details/78416176

默认情况下 javap 会打印所有非私有的字段和方法,
-p 打印私有的字段和方法。
-v 打印所有信息。
-c 查阅方法对应的字节码

附:

一只懂JVM参数的狐狸

代码验证

@Slf4j
public class JvmTest { private byte[] memory; public JvmTest(byte[] memory) {
this.memory = memory;
} public static void main(String[] args) throws InterruptedException { GC测试();
//死循环();
//死锁();
} public static void GC测试() throws InterruptedException {
for (int i = 1; i < 5; i++) {
byte[] b = new byte[50 * 1024 * 1024];
log.info("分配了50M空间给数组");
Thread.sleep(10000);
}
//方法区中常量引用对象 (虚拟机栈(栈帧中的局部变量)中引用的对象 - 方法区中的静态变量引用的对象 - 本地方法栈中JNI(即一般说的Native方法)中引用的对象)
JvmTest jvmTest = new JvmTest(new byte[50 * 1024 * 1024]);
log.info("分配了50M空间给对象");
log.info("调用了System.gc()");
System.gc();
jvmTest = null;
Thread.sleep(10000);
log.info("调用了System.gc()");
System.gc();
Thread.sleep(3000000);
} public static void 死循环() {
while (true) {
}
} public static void 死锁() {
String obj1 = "obj1";
String obj2 = "obj2";
Runnable r1 = () -> {
log.info("r1 running");
while (true) {
synchronized (obj1) {
log.info("r1 lock obj1");
try {
//获取obj1后先等一会儿,让Lock2有足够的时间锁住obj2
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (obj2) {
log.info("r1 lock obj2");
}
}
}
};
Runnable r2 = () -> {
log.info("r2 running");
while (true) {
synchronized (obj2) {
log.info("r2 lock obj2");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (obj1) {
log.info("r2 lock obj1");
}
}
}
};
Thread a = new Thread(r1);
Thread b = new Thread(r2);
a.start();
b.start();
}
}

Java之JVM监控工具分享的更多相关文章

  1. Java内存泄露监控工具:JVM监控工具介绍

    本文将对JVM监控工具jstack, jconsole, jinfo, jmap, jdb, jstat进行详细的介绍,具体内容请看下文 Sun JDK监控和故障处理工具 名称 主要作用 jps JV ...

  2. Java JVM监控工具JConsole简介

    Java JVM监控工具JConsole简介 jconsole命令 功能:打开java监视管理控制台 方法: jconsole [选项1] [选项2] …… [选项n] 常用选项: -help     ...

  3. Java线程及Jvm监控工具

    Java线程状态 线程的五种状态 * 新建:new(时间很短) * 运行:runnable * 等待:waitting(无限期等待),timed waitting(限期等待) * 阻塞:blocked ...

  4. Java 性能分析工具 , 第 2 部分:Java 内置监控工具

    引言 本文为 Java 性能分析工具系列文章第二篇,第一篇:操作系统工具.在本文中将介绍如何使用 Java 内置监控工具更加深入的了解 Java 应用程序和 JVM 本身.在 JDK 中有许多内置的工 ...

  5. JVM监控工具介绍

    JVM监控工具介绍 VisualVM是一种集成了多个JDK命令行工具的可视化工具,它能为您提供强大的分析能力.所有这些都是免费的!它囊括的命令行工具包括jps,jstat,jmap,jinfo,jst ...

  6. JProfiler - Java的性能监控工具

    简介 JProfiler是一款Java的性能监控工具.可以查看当前应用的对象.对象引用.内存.CPU使用情况.线程.线程运行情况(阻塞.等待等),同时可以查找应用内存使用得热点,即:哪个对象占用的内存 ...

  7. jvm 监控工具

    背景 不懂jvm监控工具好意思说自己搞java的吗.其实搞了十多年的人我都见过不懂得,不懂不要紧,老实工作就行啊.这就是属于非技术的话题了,实在不知从何说起.还是赶紧学习下吧,可以去装了.我认真学习后 ...

  8. Java虚拟机JVM相关知识整理

    Java虚拟机JVM的作用: Java源文件(.java)通过编译器编译成.class文件,.class文件通过JVM中的解释器解释成特定机器上的机器代码,从而实现Java语言的跨平台. JVM的体系 ...

  9. jvm虚拟机分享课笔记

    深入理解jvm虚拟机分享 1. jvm执行流程 java-编译-.class—类加载器(随时随地加载)--[进入java虚拟机] 执行引擎—本地方法接口---本地方法库 运行时数据区 2. 运行时数据 ...

随机推荐

  1. IntelliJ IDEA使用maven-javadoc-plugin生成Java Doc控制台乱码

    问题描述 在使用IDEA生成Java Doc的过程中,发现IDEA控制台乱码,作为有轻微代码强迫症的我来说,这是不可忍受的,需要鼓捣一番.先上pom.xml中的javadoc插件配置 <!--配 ...

  2. notepad++使用收集

    一. 列编辑: 按住alt+鼠标纵向选中:alt+shift+箭头纵向或者横向选中. 列块编辑(编辑->列块编辑),实现跨步增加数字写入或者补0写入. 二. 多行变一行: 1.按Ctrl+F,弹 ...

  3. wpf 控件添加背景图片

    方法一,xaml中: <控件> <控件.Background> <ImageBrush ImageSource="/WpfApplication1;compon ...

  4. 几种序列化协议(protobuf,xstream,jackjson,jdk,hessian)相关数据对比

    测试结果 序列化数据对比 bytes字节数对比 具体的数字:   protobuf jackson xstream Serializable hessian2 hessian2压缩 hessian1 ...

  5. [Oracle] “表中有数据,但select count(*)的结果为0”问题的解决办法

    一.问题 今天遇到了一个神奇的问题--表中有数据,但select count(*)的结果为0. 这个问题最初的表现形式是"查询报表没有分页". 最开始还以为是java端的问题.后来 ...

  6. 【Linux】磁盘读写 测试

    一.如何查看当前磁盘的IO使用情况 使用命令:iotop Total DISK READ: 3.89 K/s | Total DISK WRITE: 0.00 B/s TID PRIO USER DI ...

  7. Docker Mysql数据库双主同步配置方法

    一.背景 可先查看第一篇<Docker Mysql数据库主从同步配置方法>介绍 二.具体操作 1.创建目录(~/test/mysql_test1): --mysql --mone --da ...

  8. easyUI 异步加载树

    $(function () { var selected = $('#depttree').tree('getSelected'); $('#depttree').tree({ checkbox: f ...

  9. Mosquitto --topic

    订阅树的概念        Mosquitto通过订阅树的方式来管理所有的topic以及客户端的订阅关系,它首先将所有的topic按照/分割并组织成一棵树结构,从根节点到树中的每个节点即组成该节点所对 ...

  10. The thumbprint of same asymmetric key is not same in 'SQL Server Connector for Microsoft Azure Key Vault' 1.0.4.0 and 'SQL Server Connector for Microsoft Azure Key

    https://support.microsoft.com/en-us/help/4470999/db-backup-problems-to-sql-server-connector-for-azur ...