Java-性能分析和监控工具深入详解

 更新时间:2023年01月17日 14:37:41   作者:ALONG20  
这篇文章主要介绍了Java-性能分析和监控工具深入详解,文章内容详细,简单易懂,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

Java监控和管理

Java监控和管理API

Java Standard Edition(Java SE)平台提供的监控和管理技术 - JMX(Java Management Extensions) 技术。

Java SE 中包含了用于监控和管理的(java.lang.management)API,通过这些 API 可以实现应用程序的自我监控,此 API 主要提供了以下信息的访问:

  • 类加载相关。
  • JVM 相关,例如运行时间、系统环境变量、用户输入参数。
  • 线程相关,例如线程状态,线程的统计信息、线程的堆栈等。
  • 内存使用情况。
  • GC 情况。
  • 死锁检测。
  • 操作系统信息。

Java 8的java.lang.management模块:

ClassLoadingMXBean:用于 Java 虚拟机的类加载系统的管理接口。

CompilationMXBean:用于 Java 虚拟机的编译系统的管理接口。

GarbageCollectorMXBean:用于 Java 虚拟机的垃圾回收的管理接口。

MemoryManagerMXBean:内存管理器的管理接口。

MemoryMXBeanJava :虚拟机的内存系统的管理接口。

MemoryPoolMXBean:内存池的管理接口。

OperatingSystemMXBean:用于操作系统的管理接口,Java 虚拟机在此操作系统上运行。

RuntimeMXBeanJava :虚拟机的运行时系统的管理接口。

ThreadMXBeanJava :虚拟机线程系统的管理接口。

Java虚拟机的监控

上面说到 Java SE 中已经内置了开箱即用的监控和管理功能,通过这些功能可以实现程序的自我监测,Java 默认已经实现了对 Java 虚拟机相关信息的监测。

下面通过一个简单的示例,演示如何通过监控管理 API 获取系统信息、编译器信息、内存信息以及垃圾收集器信息。

 public static void main(String[] args) {

        showJvmInfo();
        showMemoryInfo();
        showSystem();
        showClassLoading();
        showCompilation();
        showThread();
        showGarbageCollector();
        showMemoryManager();
        showMemoryPool();
    }

    /**
     * Java 虚拟机的运行时系统
     */
    public static void showJvmInfo() {
        RuntimeMXBean rtMxBean = ManagementFactory.getRuntimeMXBean();
        System.out.println("Java 虚拟机的运行时系统(RuntimeMXBean):");
        System.out.println("jvm vendor:" + rtMxBean.getVmVendor());
        System.out.println("jvm name:" + rtMxBean.getVmName());
        System.out.println("jvm version:" + rtMxBean.getVmVersion());
        System.out.println("jvm bootClassPath:" + rtMxBean.getBootClassPath());
        System.out.println("jvm start time:" + rtMxBean.getStartTime());
        System.out.println("\n");
    }

    /**
     * Java 虚拟机的内存系统
     */
    public static void showMemoryInfo() {
        MemoryMXBean memoryMxBean = ManagementFactory.getMemoryMXBean();
        MemoryUsage heap = memoryMxBean.getHeapMemoryUsage();
        System.out.println("Java 虚拟机的内存系统(MemoryMXBean):");
        System.out.println("Heap " + heap.toString());
        System.out.println(
                "Heap" +
                        " init:" + heap.getInit() + byte2Mb(heap.getInit()) +
                        " used:" + byte2Mb(heap.getUsed()) +
                        " committed:" + byte2Mb(heap.getCommitted()) +
                        " max:" + byte2Mb(heap.getMax()));
        System.out.println("\n");
    }

    private static String byte2Mb(long source) {
        return "(" + source / 1024 / 1024 + "mb)";
    }

    /**
     * Java 虚拟机在其上运行的操作系统
     */
    public static void showSystem() {
        OperatingSystemMXBean operatingSystemMxBean = ManagementFactory.getOperatingSystemMXBean();
        System.out.println("Java 虚拟机在其上运行的操作系统(OperatingSystemMXBean):");
        System.out.println("Architecture(操作系统架构): " + operatingSystemMxBean.getArch());
        System.out.println("Processors(Java虚拟机可用的处理器数): " + operatingSystemMxBean.getAvailableProcessors());
        System.out.println("System name(操作系统名称): " + operatingSystemMxBean.getName());
        System.out.println("System version(操作系统版本): " + operatingSystemMxBean.getVersion());
        System.out.println("Last minute load(最后一分钟的系统负载平均值): " + operatingSystemMxBean.getSystemLoadAverage());
        System.out.println("\n");
    }

    /**
     * Java 虚拟机的类加载系统
     */
    public static void showClassLoading() {
        ClassLoadingMXBean classLoadingMxBean = ManagementFactory.getClassLoadingMXBean();
        System.out.println("Java 虚拟机的类加载系统(ClassLoadingMXBean):");
        System.out.println("TotalLoadedClassCount(加载的类总数): " + classLoadingMxBean.getTotalLoadedClassCount());
        System.out.println("LoadedClassCount(当前加载的类的数量)" + classLoadingMxBean.getLoadedClassCount());
        System.out.println("UnloadedClassCount(卸载类的总数):" + classLoadingMxBean.getUnloadedClassCount());
        System.out.println("\n");
    }

    /**
     * Java 虚拟机的编译系统
     */
    public static void showCompilation() {
        CompilationMXBean compilationMxBean = ManagementFactory.getCompilationMXBean();
        System.out.println("Java 虚拟机的编译系统(CompilationMXBean):");
        System.out.println("TotalCompilationTime(编译时间(毫秒)):" + compilationMxBean.getTotalCompilationTime());
        System.out.println("name(JIT编译器的名称):" + compilationMxBean.getName());
        System.out.println("\n");
    }

    /**
     * Java 虚拟机的线程系统
     */
    public static void showThread() {
        ThreadMXBean threadMxBean = ManagementFactory.getThreadMXBean();
        System.out.println("Java 虚拟机的线程系统(ThreadMXBean):");
        System.out.println("ThreadCount(当前活动线程数)" + threadMxBean.getThreadCount());
        System.out.println("PeakThreadCount(峰值实时线程计数)" + threadMxBean.getPeakThreadCount());
        System.out.println("TotalStartedThreadCount(启动的线程总数)" + threadMxBean.getTotalStartedThreadCount());
        System.out.println("DaemonThreadCount(当前活动后台进程线程数)" + threadMxBean.getDaemonThreadCount());
        System.out.println("isSynchronizerUsageSupported(虚拟机是否支持监视可下载同步器的使用情况)" + threadMxBean.isSynchronizerUsageSupported());
        System.out.println("AllThreadIds(所有活动线程ID):" + JSON.toJSONString(threadMxBean.getAllThreadIds()));
        System.out.println("CurrentThreadUserTime(当前线程在用户模式下执行的CPU时间(以纳秒为单位))" + threadMxBean.getCurrentThreadUserTime());
        for (ThreadInfo threadInfo : threadMxBean.getThreadInfo(threadMxBean.getAllThreadIds(), 1)) {
            System.out.print(threadInfo.getThreadId() + threadInfo.toString());
        }
        System.out.println("\n");
    }

    /**
     * Java 虚拟机中的垃圾回收器。
     */
    public static void showGarbageCollector() {
        List<GarbageCollectorMXBean> collectorMxBeans = ManagementFactory.getGarbageCollectorMXBeans();
        System.out.println("Java 虚拟机中的垃圾回收器(GarbageCollectorMXBean):");
        for (GarbageCollectorMXBean collectorMxBean : collectorMxBeans) {
            System.out.println("name(垃圾收集器名称):" + collectorMxBean.getName());
            System.out.println("--CollectionCount:" + collectorMxBean.getCollectionCount());
            System.out.println("--CollectionTime" + collectorMxBean.getCollectionTime());
            System.out.println("\n");
        }
        System.out.println("\n");
    }

    /**
     * Java 虚拟机中的内存管理器
     */
    public static void showMemoryManager() {
        List<MemoryManagerMXBean> memoryManagerMxBeans = ManagementFactory.getMemoryManagerMXBeans();
        System.out.println("Java 虚拟机中的内存管理器(MemoryManagerMXBean):");
        for (MemoryManagerMXBean managerMxBean : memoryManagerMxBeans) {
            System.out.println("name(内存管理器名称):" + managerMxBean.getName());
            System.out.println("--MemoryPoolNames:" + String.join(",", managerMxBean.getMemoryPoolNames()));
            System.out.println("\n");
        }
        System.out.println("\n");
    }

    /**
     * Java 虚拟机中的内存池
     */
    public static void showMemoryPool() {
        List<MemoryPoolMXBean> memoryPoolMxBeans = ManagementFactory.getMemoryPoolMXBeans();
        System.out.println("Java 虚拟机中的内存池(MemoryPoolMXBean):");
        for (MemoryPoolMXBean memoryPoolMxBean : memoryPoolMxBeans) {
            System.out.println("name:" + memoryPoolMxBean.getName());
            System.out.println("--CollectionUsage:" + memoryPoolMxBean.getCollectionUsage());
            System.out.println("--type:" + memoryPoolMxBean.getType());
            System.out.println("\n");
        }
        System.out.println("\n");
    }
}

输出:

Java 虚拟机的运行时系统(RuntimeMXBean):
jvm vendor:Oracle Corporation
jvm name:Java HotSpot(TM) 64-Bit Server VM
jvm version:25.221-b11
jvm bootClassPath:F:\opt\Java\jdk8\jre\lib\resources.jar;F:\opt\Java\jdk8\jre\lib\rt.jar;F:\opt\Java\jdk8\jre\lib\sunrsasign.jar;F:\opt\Java\jdk8\jre\lib\jsse.jar;F:\opt\Java\jdk8\jre\lib\jce.jar;F:\opt\Java\jdk8\jre\lib\charsets.jar;F:\opt\Java\jdk8\jre\lib\jfr.jar;F:\opt\Java\jdk8\jre\classes
jvm start time:1673181328952

Java 虚拟机的内存系统(MemoryMXBean):
Heap init = 268435456(262144K) used = 4028824(3934K) committed = 257425408(251392K) max = 3791650816(3702784K)
Heap init:268435456(256mb) used:(3mb) committed:(245mb) max:(3616mb)

Java 虚拟机在其上运行的操作系统(OperatingSystemMXBean):
Architecture(操作系统架构): amd64
Processors(Java虚拟机可用的处理器数): 8
System name(操作系统名称): Windows 10
System version(操作系统版本): 10.0
Last minute load(最后一分钟的系统负载平均值): -1.0

Java 虚拟机的类加载系统(ClassLoadingMXBean):
TotalLoadedClassCount(加载的类总数): 507
LoadedClassCount(当前加载的类的数量)507
UnloadedClassCount(卸载类的总数):0

Java 虚拟机的编译系统(CompilationMXBean):
TotalCompilationTime(编译时间(毫秒)):8
name(JIT编译器的名称):HotSpot 64-Bit Tiered Compilers

Java 虚拟机的线程系统(ThreadMXBean):
ThreadCount(当前活动线程数)5
PeakThreadCount(峰值实时线程计数)5
TotalStartedThreadCount(启动的线程总数)5
DaemonThreadCount(当前活动后台进程线程数)4
isSynchronizerUsageSupported(虚拟机是否支持监视可下载同步器的使用情况)true
AllThreadIds(所有活动线程ID):[5,4,3,2,1]
CurrentThreadUserTime(当前线程在用户模式下执行的CPU时间(以纳秒为单位))234375000
5"Attach Listener" Id=5 RUNNABLE

4"Signal Dispatcher" Id=4 RUNNABLE

3"Finalizer" Id=3 WAITING on java.lang.ref.ReferenceQueue$Lock@17c68925
	at java.lang.Object.wait(Native Method)
	-  waiting on java.lang.ref.ReferenceQueue$Lock@17c68925

2"Reference Handler" Id=2 WAITING on java.lang.ref.Reference$Lock@7e0ea639
	at java.lang.Object.wait(Native Method)
	-  waiting on java.lang.ref.Reference$Lock@7e0ea639

1"main" Id=1 RUNNABLE
	at sun.management.ThreadImpl.getThreadInfo1(Native Method)

Java 虚拟机中的垃圾回收器(GarbageCollectorMXBean):
name(垃圾收集器名称):PS Scavenge
--CollectionCount:0
--CollectionTime0

name(垃圾收集器名称):PS MarkSweep
--CollectionCount:0
--CollectionTime0

Java 虚拟机中的内存管理器(MemoryManagerMXBean):
name(内存管理器名称):CodeCacheManager
--MemoryPoolNames:Code Cache

name(内存管理器名称):Metaspace Manager
--MemoryPoolNames:Metaspace,Compressed Class Space

name(内存管理器名称):PS Scavenge
--MemoryPoolNames:PS Eden Space,PS Survivor Space

name(内存管理器名称):PS MarkSweep
--MemoryPoolNames:PS Eden Space,PS Survivor Space,PS Old Gen

Java 虚拟机中的内存池(MemoryPoolMXBean):
name:Code Cache
--CollectionUsage:null
--type:Non-heap memory

name:Metaspace
--CollectionUsage:null
--type:Non-heap memory

name:Compressed Class Space
--CollectionUsage:null
--type:Non-heap memory

name:PS Eden Space
--CollectionUsage:init = 67108864(65536K) used = 0(0K) committed = 0(0K) max = 1399848960(1367040K)
--type:Heap memory

name:PS Survivor Space
--CollectionUsage:init = 11010048(10752K) used = 0(0K) committed = 0(0K) max = 11010048(10752K)
--type:Heap memory

name:PS Old Gen
--CollectionUsage:init = 179306496(175104K) used = 0(0K) committed = 0(0K) max = 2843738112(2777088K)
--type:Heap memory

Disconnected from the target VM, address: '127.0.0.1:12687', transport: 'socket'

Process finished with exit code 0

Java监控和管理工具

JMX 技术中提到 JMX 不仅提供了监控和管理的 API ,还提供了用于网络远程管理的服务,可以使用 JMX 相关监控管理工具,通过网络远程连接到正在运行 Java 虚拟机,监控其运行状态。

JMC(Java Mission Control)

Java Mission Control使您能够监视和管理Java应用程序,而不会引入通常与这些类型的工具相关联的性能开销。

它使用为Java虚拟机(JVM)的常规自适应动态优化收集的数据。

除了最小化性能开销之外,这种方法还消除了观察器效应的问题,当监视工具改变系统的执行特性时会发生这种问题。

Java Mission Control由客户端应用程序(JMC客户端)和在其上运行的许多插件组成:

  • JVM Browser显示正在运行的Java应用程序及其JVM。每个JVM实例都称为JVM连接。
  • JMX Console连接到正在运行的JVM,实时收集和显示其特征,并允许您通过Managed Beans(MBean)更改某些运行时属性。您还可以创建触发某些事件的规则(例如,如果应用程序的CPU使用率达到90%,则发送电子邮件)。
  • Java Flight Recorder(JFR)收集并保存详细的性能特征,以进行历史分析和分析。它可以用作独立的性能监视和分析工具,但是当用作JMC客户端的插件时,它会在逻辑分组的表,图表和拨号中显示诊断信息。它使您可以选择专注于问题所需的时间范围和详细程度。
  • Java Mission Control插件使用Java Management Extensions(JMX)代理连接到JVM。

启动JMC

双击JAvA_HOME\bin\jmc.exe 文件启动JMC

连接远程程序添加配置:

 -Dcom.sun.management.jmxremote.port=7001
 -Dcom.sun.management.jmxremote 
 -Dcom.sun.management.jmxremote.authenticate=false 
 -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=your ip

JMC功能介绍

MBean浏览器中查看类属性信息:

内存栏目查看GC、各个内存区域使用情况:

线程状态、死锁、堆栈信息:

诊断命令,查询vm信息等:

JFR(Java Flight Recorder)

黑匣子是用于记录飞机飞行和性能参数的仪器。在飞机出问题后,用于定位问题原因。JFR 就是 Java 的黑匣子。

JFR 是 Java Flight Record (Java飞行记录) 的缩写,是 JVM 内置的基于事件的JDK监控记录框架。

这个起名就是参考了黑匣子对于飞机的作用,将Java进程比喻成飞机飞行。

顾名思义,这个记录主要用于问题定位和持续监控。

如果是利用默认配置启动这个记录,性能非常高效,对于业务影响很小,因为这个框架本来就是用来长期在线上部署的框架。

这个记录可以输出成二进制文件,用户可以指定最大记录时间,或者最大记录大小,供用户在需要的时候输出成文件进行事后分析。

JFR在Java应用运行时收集对应发生的事件,主要有三种类型的事件提供给JFR收集:

  • 即时事件:一旦事件发生会立即进行数据记录
  • 持续事件:如果持续时间超过指定阈值则进行数据记录
  • 简单事件:用于记录应用所在系统的活跃指标(例如CPU,内存等)

开启JFR记录

通过启动参数配置并且启用 JFR,也可以通过启动参数在 JVM 进程启动的时候就启动 JFR,或者是利用 jcmd 工具,动态启用或者关闭 JFR。

JDK 8中的-XX:+FlightRecorder

java -XX:StartFlightRecording=disk=true,dumponexit=true,filename=recording.jfr,maxsize=1024m,maxage=1d,settings=profile,path-to-gc-roots=true test.Main

JConsole

Jconsole (Java Monitoring and Management Console),一种基于JMX的可视化监视、管理工具。

JConsole 基本包括以下基本功能:概述、内存、线程、类、VM概要、MBean。

概述

内存

线程

可以看到线程列表、线程状态、线程名称、线程堆栈等信息。

可以看到 已加装当前类、已加载类总数、已卸载类总数。

VM

MXBean

JVisualVM

VisualVM(All-in-One Java Troubleshooting Tool);功能最强大的运行监视和故障处理程序。

功能描述:

  • 显示虚拟机进程以及进程的配置环境信息(jps、jinfo)。
  • 监视应用程序的CPUGC方法区(1.7及以前),元空间(JDK1.8及以后)以及线程的信息(jstat、jstack)。
  • dump以及分析堆转储快照(jmap、jhat)。
  • 方法级的程序运行性能分析,找出被调用最多、运行时间最长的方法。
  • 离线程序快照:收集程序的运行时配置、线程dump、内存dump等信息建立一个快照。

Java Management Extensions(JMX)

以上就是Java-性能分析和监控工具深入详解的详细内容,更多关于Java-性能分析&监控工具的资料请关注脚本之家其它相关文章!

相关文章

  • Spring Bean实例的创建及构造器的挑选

    Spring Bean实例的创建及构造器的挑选

    这篇文章主要介绍了Spring Bean实例的创建及构造器的挑选,文中有非常详细的代码示例,对正在学习java的小伙伴们有很好的帮助,需要的朋友可以参考下
    2021-04-04
  • java按字节截取带有汉字的字符串的解法(推荐)

    java按字节截取带有汉字的字符串的解法(推荐)

    下面小编就为大家带来一篇java按字节截取带有汉字的字符串的解法(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-09-09
  • Java中常用的数据库连接池_动力节点Java学院整理

    Java中常用的数据库连接池_动力节点Java学院整理

    数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏
    2017-08-08
  • 5个步骤让你明白多线程和线程安全

    5个步骤让你明白多线程和线程安全

    本文详细讲解了多线程和线程安全的实现,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-12-12
  • Java基础入门语法--String类

    Java基础入门语法--String类

    字符串广泛应用在Java编程中,在Java中字符串属于对象,Java 提供了String类来创建和操作字符串,今天给大家介绍Java基础入门语法--String类的相关知识,感兴趣的朋友一起看看吧
    2021-06-06
  • 动态更改Spring定时任务Cron表达式的优雅方案实例详解

    动态更改Spring定时任务Cron表达式的优雅方案实例详解

    spring定时器非常强大,但是有时候我们需要在不需要重启应用就可以动态的改变Cron表达式的值,下面这篇文章主要给大家介绍了关于动态更改Spring定时任务Cron表达式的优雅方案,需要的朋友可以参考下
    2022-12-12
  • java如何完成输出语句实例详解

    java如何完成输出语句实例详解

    输入输出可以说是计算机的基本功能,下面这篇文章主要给大家介绍了关于java如何完成输出语句的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-01-01
  • 一文带你了解Java中的Object类及类中方法

    一文带你了解Java中的Object类及类中方法

    Object是Java默认提供的一个类。Java里面除了Object类,所有的类都是存在继承关系的。默认会继承Object父 类。即所有类的对象都可以使用Object的引用进行接收。本文就来为大家详细讲讲Object类及类中方法,感兴趣的可以了解一下
    2022-08-08
  • 详解高性能缓存Caffeine原理及实战

    详解高性能缓存Caffeine原理及实战

    Caffeine是基于Java 8开发的,提供了近乎最佳命中率的高性能本地缓存组件,Spring5开始不再支持Guava Cache,改为使用Caffeine。Caffeine提供的内存缓存使用参考Google guava的API
    2021-06-06
  • Java Scoket实现双向通信代码详解

    Java Scoket实现双向通信代码详解

    这篇文章主要介绍了Java Scoket实现双向通信代码详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06

最新评论