Java之JVM监控工具分享

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();
    }
}

原文地址:https://www.cnblogs.com/loveincode/p/10577550.html

时间: 2024-10-09 10:53:23

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

Java线程及Jvm监控工具

Java线程状态 线程的五种状态 * 新建:new(时间很短) * 运行:runnable * 等待:waitting(无限期等待),timed waitting(限期等待) * 阻塞:blocked * 结束:terminated(时间很短) Jvm监控工具 一.jstack 介绍: jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息.如果是在64位机器上,需要指定选项"-J-d64",Windows的jstack使用方式只支持以下的这种

JVM监控工具用法指导

JVM监控工具用法指导 2010-09-27 15:39 dolphin-ygj javaeye.com 字号:T | T 通过JVM监控工具的使用可以及时发现问题,剔除安全隐患,这里向大家描述一下常用的几个JVM监控工具的用法,希望对你的学习有所帮助. AD:51CTO 网+首届APP创新评选大赛火热启动——超百万资源等你拿! 这里向大家描述一下JVM监控工具的用法,比如jstatd,启动jvm监控服务.它是一个基于rmi的应用,向远程机器提供本机jvm应用程序的信息.默认端口1099. JV

JVM监控工具介绍

JVM监控工具介绍 VisualVM是一种集成了多个JDK命令行工具的可视化工具,它能为您提供强大的分析能力.所有这些都是免费的!它囊括的命令行工具包括jps,jstat,jmap,jinfo,jstack,JConsole,这些工具与JDK的标准版本是一致的. jps:与unix上的ps类似,用来显示本地的java进程,可以查看本地运行着几个java程序,并显示他们的进程号. jstat:一个极强的监视VM内存工具.可以用来监视VM内存内的各种堆和非堆的大小及其内存使用量. jmap:打印出某

Java application 性能分析分享

性能分析的主要方式 监视:监视是一种用来查看应用程序运行时行为的一般方法.通常会有多个视图(View)分别实时地显示 CPU 使用情况.内存使用情况.线程状态以及其他一些有用的信息,以便用户能很快地发现问题的关键所在. 转储:性能分析工具从内存中获得当前状态数据并存储到文件用于静态的性能分析.Java 程序是通过在启动 Java 程序时添加适当的条件参数来触发转储操作的.它包括以下三种: 系统转储:JVM 生成的本地系统的转储,又称作核心转储.一般的,系统转储数据量大,需要平台相关的工具去分析,

JAVA和JVM运行原理揭秘

这里和大家简单分享一下JAVA和JVM运行的原理,Java语言写的源程序通过Java编译器,编译成与平台无关的‘字节码程序’(.class文件,也就是0,1二进制程序),然后在OS之上的Java解释器中解释执行,而JVM是java的核心和基础,在java编译器和os平台之间的虚拟处理器. 1.Java语言运行的过程 Java语言写的源程序通过Java编译器,编译成与平台无关的‘字节码程序’(.class文件,也就是0,1二进制程序),然后在OS之上的Java解释器中解释执行. 注:JVM(jav

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

引言 本文为 Java 性能分析工具系列文章第二篇,第一篇:操作系统工具.在本文中将介绍如何使用 Java 内置监控工具更加深入的了解 Java 应用程序和 JVM 本身.在 JDK 中有许多内置的工具,其中包括: jcmd:打印一个 Java 进程的类,线程以及虚拟机信息.适合用在脚本中.使用 jcmd - h 来查看使用方法. jconsole:提供 JVM 活动的图形化展示,包括线程使用,类使用以及垃圾回收(GC)信息. jhat:帮助分析内存堆存储. jmap:提供 JVM 内存使用信息

java虚拟机内存监控工具jps,jinfo,Jstack,jstat,jmap,jhat使用

基于Sun HotSpot JVM 这里将介绍几款sun hotspot jvm 自带的监控工具: 请确保java_home/bin配置到path环境变量下,因为这些工具都在jdk的bin目录下 jps(JVM Process Status Tool):JVM机进程状况工具 用来查看基于HotSpot JVM里面所有进程的具体状态, 包括进程ID,进程启动的路径等等.与unix上的ps类似,用来显示本地有权限的java进程,可以查看本地运行着几个java程序,并显示他们的进程号.使用jps时,不

书籍推荐:《实战Java虚拟机——JVM故障诊断与性能优化》下载

本书详细介绍Java虚拟机的基本原理和优化诊断方法.其中重点介绍Java虚拟机的体系结构.常用的虚拟机参数.Java虚拟机的垃圾回收原理.算法以及目前虚拟机所支持的各种垃圾回收器及其区别.特点和使用方法.在实践和调优方面,重点介绍了Java的堆.栈分析方法,性能调优的一般思路.手段和工具.此外,还详细介绍了虚拟机内有关"锁"的实现以及优化方法. 作为对虚拟机的深入了解,本书还将详细介绍Java类的基本格式.装载过程和虚拟机的执行机制. Java虚拟机目前是Java.Scala.Cloj

JVM监控工具之JProfiler

一.简介 JProfiler是一款Java的性能监控工具.可以查看当前应用的对象.对象引用.内存.CPU使用情况,线程运行情况(阻塞.等待等),同时可以查找哪个对象占用的内存比较多.哪个对象占用CPU处理的时间比较多 二.配置 通过JProfiler远程连接服务器监控JVM,需要在被监控的服务器上tomcat的启动文件catalina.sh中加入以下配置: JAVA_OPTS="-agentpath:/usr/local/jprofiler7/bin/linux-x86/libjprofiler