Java-性能分析监控工具
创始人
2024-05-09 00:57:27
0

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 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 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 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:1673181328952Java 虚拟机的内存系统(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.0Java 虚拟机的类加载系统(ClassLoadingMXBean):
TotalLoadedClassCount(加载的类总数): 507
LoadedClassCount(当前加载的类的数量)507
UnloadedClassCount(卸载类的总数):0Java 虚拟机的编译系统(CompilationMXBean):
TotalCompilationTime(编译时间(毫秒)):8
name(JIT编译器的名称):HotSpot 64-Bit Tiered CompilersJava 虚拟机的线程系统(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 RUNNABLE4"Signal Dispatcher" Id=4 RUNNABLE3"Finalizer" Id=3 WAITING on java.lang.ref.ReferenceQueue$Lock@17c68925at java.lang.Object.wait(Native Method)-  waiting on java.lang.ref.ReferenceQueue$Lock@17c689252"Reference Handler" Id=2 WAITING on java.lang.ref.Reference$Lock@7e0ea639at java.lang.Object.wait(Native Method)-  waiting on java.lang.ref.Reference$Lock@7e0ea6391"main" Id=1 RUNNABLEat sun.management.ThreadImpl.getThreadInfo1(Native Method)Java 虚拟机中的垃圾回收器(GarbageCollectorMXBean):
name(垃圾收集器名称):PS Scavenge
--CollectionCount:0
--CollectionTime0name(垃圾收集器名称):PS MarkSweep
--CollectionCount:0
--CollectionTime0Java 虚拟机中的内存管理器(MemoryManagerMXBean):
name(内存管理器名称):CodeCacheManager
--MemoryPoolNames:Code Cachename(内存管理器名称):Metaspace Manager
--MemoryPoolNames:Metaspace,Compressed Class Spacename(内存管理器名称):PS Scavenge
--MemoryPoolNames:PS Eden Space,PS Survivor Spacename(内存管理器名称):PS MarkSweep
--MemoryPoolNames:PS Eden Space,PS Survivor Space,PS Old GenJava 虚拟机中的内存池(MemoryPoolMXBean):
name:Code Cache
--CollectionUsage:null
--type:Non-heap memoryname:Metaspace
--CollectionUsage:null
--type:Non-heap memoryname:Compressed Class Space
--CollectionUsage:null
--type:Non-heap memoryname:PS Eden Space
--CollectionUsage:init = 67108864(65536K) used = 0(0K) committed = 0(0K) max = 1399848960(1367040K)
--type:Heap memoryname:PS Survivor Space
--CollectionUsage:init = 11010048(10752K) used = 0(0K) committed = 0(0K) max = 11010048(10752K)
--type:Heap memoryname:PS Old Gen
--CollectionUsage:init = 179306496(175104K) used = 0(0K) committed = 0(0K) max = 2843738112(2777088K)
--type:Heap memoryDisconnected 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
配置key默认值说明
delay0延迟多久后启动 JFR 记录,支持带单位配置, 例如 delay=60s(秒), delay=20m(分钟), delay=1h(小时), delay=1d(天),不带单位就是秒, 0就是没有延迟直接开始记录。一般为了避免框架初始化等影响,我们会延迟 1 分钟开始记录(例如Spring cloud应用,可以看下日志中应用启动耗时,来决定下这个时间)。
disktrue是否写入磁盘,这个就是上文提到的, global buffer 满了之后,是直接丢弃还是写入磁盘文件。
dumponexitfalse程序退出时,是否要dump出 .jfr文件
duration0JFR 记录持续时间,同样支持单位配置,不带单位就是秒,0代表不限制持续时间,一直记录。
filename启动目录/hotspot-pid-26732-id-1-2020_03_12_10_07_22.jfr,pid 后面就是 pid, id 后面是第几个 JFR 记录,可以启动多个 JFR 记录。最后就是时间。dump的输出文件
name记录名称,由于可以启动多个 JFR 记录,这个名称用于区分,否则只能看到一个记录 id,不好区分。
maxage0这个参数只有在 disk 为 true 的情况下才有效。最大文件记录保存时间,就是 global buffer 满了需要刷入本地临时目录下保存,这些文件最多保留多久的。也可以通过单位配置,没有单位就是秒,默认是0,就是不限制
maxsize250MB这个参数只有在 disk 为 true 的情况下才有效。最大文件大小,支持单位配置, 不带单位是字节,m或者M代表MB,g或者G代表GB。设置为0代表不限制大小**。虽然官网说默认就是0,但是实际用的时候,不设置会有提示**: No limit specified, using maxsize=250MB as default. 注意,这个配置不能小于后面将会提到的 maxchunksize 这个参数。
path-to-gc-rootsfalse是否记录GC根节点到活动对象的路径,一般不打开这个,首先这个在我个人定位问题的时候,很难用到,只要你的编程习惯好。还有就是打开这个,性能损耗比较大,会导致FullGC一般是在怀疑有内存泄漏的时候热启动这种采集,并且通过产生对象堆栈无法定位的时候,动态打开即可。一般通过产生这个对象的堆栈就能定位,如果定位不到,怀疑有其他引用,例如 ThreadLocal 没有释放这样的,可以在 dump 的时候采集 gc roots
settings默认是 default.jfc,这个位于 $JAVA_HOME/lib/jfr/default.jfc采集 Event 的详细配置,采集的每个 Event 都有自己的详细配置。另一个 JDK 自带的配置是 profile.jfc,位于 $JAVA_HOME/lib/jfr/profile.jfc。这个配置文件里面的配置是怎么回事,我们后面会涉及。

感兴趣可以看看:
https://juejin.cn/post/6959405798556434440
https://zhuanlan.zhihu.com/p/87850586

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)

相关内容

热门资讯

安卓系统的手机优缺点,全面解析... 你有没有发现,现在市面上手机种类繁多,让人挑花了眼?其中,安卓系统的手机可是占据了半壁江山呢!今天,...
平板有没有安卓系统,安卓系统引... 你有没有想过,平板电脑到底有没有安卓系统呢?这个问题听起来可能有点奇怪,但确实很多人在选购平板时都会...
安卓手机双系统好用不,安卓手机... 你有没有想过,你的安卓手机是不是也能像多面手一样,既能驾驭工作,又能享受娱乐呢?没错,说的就是那个神...
安卓系统怎么登录国际服,一键操... 你有没有想过,为什么有时候你的安卓手机上会出现那些国际服的游戏呢?是不是好奇怎么登录这些神秘的国外服...
安卓系统的时间天气没了,天气功... 最近你的安卓手机是不是也遇到了一个让人头疼的小问题?那就是——时间天气不见了!没错,就是那个曾经陪伴...
安卓好用的拍照系统,捕捉美好瞬... 你有没有发现,现在手机拍照功能越来越强大了?尤其是安卓手机,拍照系统简直让人爱不释手!今天,就让我带...
软件如何兼容安卓8系统,助您软... 你有没有发现,随着科技的飞速发展,手机软件更新换代的速度也是越来越快呢!这不,安卓8系统已经悄然来临...
安卓通用版系统下载,畅享智能生... 你有没有发现,最近手机界又掀起了一股热潮?没错,就是安卓通用版系统下载!这可是个让无数安卓用户兴奋不...
安卓无线点餐系统ph,PH技术... 你有没有想过,点餐也能变得如此轻松愉快?没错,就是那个我们每天都要面对的吃饭问题,现在有了安卓无线点...
安卓门禁系统怎么样,便捷通行新... 你有没有想过,每天回家时,只需轻轻一刷,门就自动打开了?这就是安卓门禁系统的魅力所在!今天,就让我带...
在电脑上模拟安卓系统,探索虚拟... 你有没有想过,在电脑上也能体验安卓系统的乐趣呢?没错,就是那种随时随地都能玩手机的感觉,现在也能在电...
飞机送餐安卓系统,空中美食新体... 你有没有想过,飞机上的美食是如何送到你手中的?是不是觉得这背后有着神秘的力量?其实,这一切都离不开高...
findx耍原生安卓系统,深度... 亲爱的读者们,你是否厌倦了那些花里胡哨的定制系统,渴望回到那个纯净的安卓世界?今天,我要带你一起探索...
一加系统属于安卓系统吗,引领智... 你有没有想过,手机里的那个神奇的“一加系统”到底是不是安卓系统的一员呢?这可是个让人好奇不已的问题哦...
小米2刷安卓系统吗,探索安卓系... 亲爱的读者,你是否曾经对小米2这款手机刷安卓系统的事情感到好奇呢?今天,就让我带你一探究竟,揭开小米...
安卓7.0系统线刷包,深度解析... 你有没有发现,你的安卓手机最近有点儿“蔫儿”了?别急,别急,今天就来给你揭秘如何让你的安卓手机重焕生...
白菜系统和安卓拍照,开启智能生... 你知道吗?最近我在用手机拍照的时候,发现了一个超级酷的功能,简直让我爱不释手!那就是——白菜系统和安...
安卓系统查杀病毒,全方位守护您... 手机里的安卓系统是不是有时候会突然弹出一个查杀病毒的提示?别慌,这可不是什么大问题,今天就来给你详细...
iso系统与安卓各系统哪个好,... 你有没有想过,手机操作系统就像是我们生活中的不同交通工具,各有各的特色和优势。今天,咱们就来聊聊这个...
中柏怎么换安卓系统,解锁更多可... 你有没有发现,中柏的安卓系统有时候用起来还挺不顺手的?别急,今天就来手把手教你如何给中柏手机升级安卓...