今天有个同事问如何能通过JMX获取到某个Java进程的full GC次数:
我回答说因为full GC概念只有在分代式GC的上下文中才存在,而JVM并不强制要求GC使用分代式实现,所以JMX提供的标准MXBean API里不提供“full GC次数”这样的方法也正常。
既然“full GC”本来就是非常平台相关的概念,那就hack一点,用平台相关的代码来解决问题好了。这些GC的MXBean都是有名字的,而主流的JVM的GC名字相对稳定,非要通过JMX得到full GC次数的话,用名字来判断一下就好了。
举个例子来看看。通过JDK 6自带的JConsole工具来查看相关的MXBean的话,可以看到,
GC的MXBean在这个位置:
这个例子是用server模式启动JConsole的,使用的是ParallelScavenge GC,它的年老代对应的收集器在这里:
该收集器的总收集次数在此,这也就是full GC的次数:
于是只要知道我们用的JVM提供的GC MXBean的名字与分代的关系,就可以知道full GC的次数了。
Java代码写起来冗长,这帖就不用Java来写例子了,反正API是一样的,意思能表达清楚就OK。
用一个Groovy脚本简单演示一下适用于Oracle (Sun) HotSpot与Oracle (BEA) JRockit的GC统计程序:
执行可以看到类似这样的输出:
↑这是用client模式的HotSpot执行得到的;
↑这是用JRockit R28在32位Windows上的默认模式得到的。
通过上述方法,要包装起来方便以后使用的话也很简单,例如下面Groovy程序:
用的时候:
这是在Sun JDK 6 update 20上跑的。顺带一提,如果这是跑在JRockit上的话,那full GC的次数就不会增加——因为JRockit里System.gc()默认是触发young GC的;请不要因为Sun HotSpot的默认行为而认为System.gc()总是会触发full GC的。
关于JMX的MXBean的使用,也可以参考下面两篇文档:
Groovy and JMX
Monitoring the JVM Heap with JRuby
引用
hi,问个问题,怎们在java中获取到full gc的次数呢?
我现在用jmx的那个得到了gc次数,不过不能细化出来full gc的次数
你比如我现在是这样拿次数的
我现在用jmx的那个得到了gc次数,不过不能细化出来full gc的次数
- for (final GarbageCollectorMXBean garbageCollector
- : ManagementFactory.getGarbageCollectorMXBeans()) {
- gcCounts += garbageCollector.getCollectionCount();
- }
for (final GarbageCollectorMXBean garbageCollector : ManagementFactory.getGarbageCollectorMXBeans()) { gcCounts += garbageCollector.getCollectionCount(); }
你比如我现在是这样拿次数的
我回答说因为full GC概念只有在分代式GC的上下文中才存在,而JVM并不强制要求GC使用分代式实现,所以JMX提供的标准MXBean API里不提供“full GC次数”这样的方法也正常。
既然“full GC”本来就是非常平台相关的概念,那就hack一点,用平台相关的代码来解决问题好了。这些GC的MXBean都是有名字的,而主流的JVM的GC名字相对稳定,非要通过JMX得到full GC次数的话,用名字来判断一下就好了。
举个例子来看看。通过JDK 6自带的JConsole工具来查看相关的MXBean的话,可以看到,
GC的MXBean在这个位置:
这个例子是用server模式启动JConsole的,使用的是ParallelScavenge GC,它的年老代对应的收集器在这里:
该收集器的总收集次数在此,这也就是full GC的次数:
于是只要知道我们用的JVM提供的GC MXBean的名字与分代的关系,就可以知道full GC的次数了。
Java代码写起来冗长,这帖就不用Java来写例子了,反正API是一样的,意思能表达清楚就OK。
用一个Groovy脚本简单演示一下适用于Oracle (Sun) HotSpot与Oracle (BEA) JRockit的GC统计程序:
- import java.lang.management.ManagementFactory
- printGCStats = {
- def youngGenCollectorNames = [
- // Oracle (Sun) HotSpot
- // -XX:+UseSerialGC
- 'Copy',
- // -XX:+UseParNewGC
- 'ParNew',
- // -XX:+UseParallelGC
- 'PS Scavenge',
- // Oracle (BEA) JRockit
- // -XgcPrio:pausetime
- 'Garbage collection optimized for short pausetimes Young Collector',
- // -XgcPrio:throughput
- 'Garbage collection optimized for throughput Young Collector',
- // -XgcPrio:deterministic
- 'Garbage collection optimized for deterministic pausetimes Young Collector'
- ]
- def oldGenCollectorNames = [
- // Oracle (Sun) HotSpot
- // -XX:+UseSerialGC
- 'MarkSweepCompact',
- // -XX:+UseParallelGC and (-XX:+UseParallelOldGC or -XX:+UseParallelOldGCCompacting)
- 'PS MarkSweep',
- // -XX:+UseConcMarkSweepGC
- 'ConcurrentMarkSweep',
- // Oracle (BEA) JRockit
- // -XgcPrio:pausetime
- 'Garbage collection optimized for short pausetimes Old Collector',
- // -XgcPrio:throughput
- 'Garbage collection optimized for throughput Old Collector',
- // -XgcPrio:deterministic
- 'Garbage collection optimized for deterministic pausetimes Old Collector'
- ]
- R: {
- ManagementFactory.garbageCollectorMXBeans.each {
- def name = it.name
- def count = it.collectionCount
- def gcType;
- switch (name) {
- case youngGenCollectorNames:
- gcType = 'Minor Collection'
- break
- case oldGenCollectorNames:
- gcType = 'Major Collection'
- break
- default:
- gcType = 'Unknown Collection Type'
- break
- }
- println "$count <- $gcType: $name"
- }
- }
- }
- printGCStats()
import java.lang.management.ManagementFactory printGCStats = { def youngGenCollectorNames = [ // Oracle (Sun) HotSpot // -XX:+UseSerialGC 'Copy', // -XX:+UseParNewGC 'ParNew', // -XX:+UseParallelGC 'PS Scavenge', // Oracle (BEA) JRockit // -XgcPrio:pausetime 'Garbage collection optimized for short pausetimes Young Collector', // -XgcPrio:throughput 'Garbage collection optimized for throughput Young Collector', // -XgcPrio:deterministic 'Garbage collection optimized for deterministic pausetimes Young Collector' ] def oldGenCollectorNames = [ // Oracle (Sun) HotSpot // -XX:+UseSerialGC 'MarkSweepCompact', // -XX:+UseParallelGC and (-XX:+UseParallelOldGC or -XX:+UseParallelOldGCCompacting) 'PS MarkSweep', // -XX:+UseConcMarkSweepGC 'ConcurrentMarkSweep', // Oracle (BEA) JRockit // -XgcPrio:pausetime 'Garbage collection optimized for short pausetimes Old Collector', // -XgcPrio:throughput 'Garbage collection optimized for throughput Old Collector', // -XgcPrio:deterministic 'Garbage collection optimized for deterministic pausetimes Old Collector' ] R: { ManagementFactory.garbageCollectorMXBeans.each { def name = it.name def count = it.collectionCount def gcType; switch (name) { case youngGenCollectorNames: gcType = 'Minor Collection' break case oldGenCollectorNames: gcType = 'Major Collection' break default: gcType = 'Unknown Collection Type' break } println "$count <- $gcType: $name" } } } printGCStats()
执行可以看到类似这样的输出:
5 <- Minor Collection: Copy 0 <- Major Collection: MarkSweepCompact
↑这是用client模式的HotSpot执行得到的;
- 0 <- Minor Collection: Garbage collection optimized for throughput Young Collector
- 0 <- Major Collection: Garbage collection optimized for throughput Old Collector
0 <- Minor Collection: Garbage collection optimized for throughput Young Collector 0 <- Major Collection: Garbage collection optimized for throughput Old Collector
↑这是用JRockit R28在32位Windows上的默认模式得到的。
通过上述方法,要包装起来方便以后使用的话也很简单,例如下面Groovy程序:
- import java.lang.management.ManagementFactory
- class GCStats {
- static final List<String> YoungGenCollectorNames = [
- // Oracle (Sun) HotSpot
- // -XX:+UseSerialGC
- 'Copy',
- // -XX:+UseParNewGC
- 'ParNew',
- // -XX:+UseParallelGC
- 'PS Scavenge',
- // Oracle (BEA) JRockit
- // -XgcPrio:pausetime
- 'Garbage collection optimized for short pausetimes Young Collector',
- // -XgcPrio:throughput
- 'Garbage collection optimized for throughput Young Collector',
- // -XgcPrio:deterministic
- 'Garbage collection optimized for deterministic pausetimes Young Collector'
- ]
- static final List<String> OldGenCollectorNames = [
- // Oracle (Sun) HotSpot
- // -XX:+UseSerialGC
- 'MarkSweepCompact',
- // -XX:+UseParallelGC and (-XX:+UseParallelOldGC or -XX:+UseParallelOldGCCompacting)
- 'PS MarkSweep',
- // -XX:+UseConcMarkSweepGC
- 'ConcurrentMarkSweep',
- // Oracle (BEA) JRockit
- // -XgcPrio:pausetime
- 'Garbage collection optimized for short pausetimes Old Collector',
- // -XgcPrio:throughput
- 'Garbage collection optimized for throughput Old Collector',
- // -XgcPrio:deterministic
- 'Garbage collection optimized for deterministic pausetimes Old Collector'
- ]
- static int getYoungGCCount() {
- ManagementFactory.garbageCollectorMXBeans.inject(0) { youngGCCount, gc ->
- if (YoungGenCollectorNames.contains(gc.name))
- youngGCCount + gc.collectionCount
- else
- youngGCCount
- }
- }
- static int getFullGCCount() {
- ManagementFactory.garbageCollectorMXBeans.inject(0) { fullGCCount, gc ->
- if (OldGenCollectorNames.contains(gc.name))
- fullGCCount + gc.collectionCount
- else
- fullGCCount
- }
- }
- }
import java.lang.management.ManagementFactory class GCStats { static final List<String> YoungGenCollectorNames = [ // Oracle (Sun) HotSpot // -XX:+UseSerialGC 'Copy', // -XX:+UseParNewGC 'ParNew', // -XX:+UseParallelGC 'PS Scavenge', // Oracle (BEA) JRockit // -XgcPrio:pausetime 'Garbage collection optimized for short pausetimes Young Collector', // -XgcPrio:throughput 'Garbage collection optimized for throughput Young Collector', // -XgcPrio:deterministic 'Garbage collection optimized for deterministic pausetimes Young Collector' ] static final List<String> OldGenCollectorNames = [ // Oracle (Sun) HotSpot // -XX:+UseSerialGC 'MarkSweepCompact', // -XX:+UseParallelGC and (-XX:+UseParallelOldGC or -XX:+UseParallelOldGCCompacting) 'PS MarkSweep', // -XX:+UseConcMarkSweepGC 'ConcurrentMarkSweep', // Oracle (BEA) JRockit // -XgcPrio:pausetime 'Garbage collection optimized for short pausetimes Old Collector', // -XgcPrio:throughput 'Garbage collection optimized for throughput Old Collector', // -XgcPrio:deterministic 'Garbage collection optimized for deterministic pausetimes Old Collector' ] static int getYoungGCCount() { ManagementFactory.garbageCollectorMXBeans.inject(0) { youngGCCount, gc -> if (YoungGenCollectorNames.contains(gc.name)) youngGCCount + gc.collectionCount else youngGCCount } } static int getFullGCCount() { ManagementFactory.garbageCollectorMXBeans.inject(0) { fullGCCount, gc -> if (OldGenCollectorNames.contains(gc.name)) fullGCCount + gc.collectionCount else fullGCCount } } }
用的时候:
- D:\>\sdk\groovy-1.7.2\bin\groovysh
- Groovy Shell (1.7.2, JVM: 1.6.0_20)
- Type 'help' or '\h' for help.
- --------------------------------------------------
- groovy:000> GCStats.fullGCCount
- ===> 0
- groovy:000> System.gc()
- ===> null
- groovy:000> GCStats.fullGCCount
- ===> 1
- groovy:000> System.gc()
- ===> null
- groovy:000> System.gc()
- ===> null
- groovy:000> GCStats.fullGCCount
- ===> 3
- groovy:000> GCStats.youngGCCount
- ===> 9
- groovy:000> GCStats.youngGCCount
- ===> 9
- groovy:000> GCStats.youngGCCount
- ===> 9
- groovy:000> System.gc()
- ===> null
- groovy:000> GCStats.youngGCCount
- ===> 9
- groovy:000> GCStats.fullGCCount
- ===> 4
- groovy:000> quit
D:\>\sdk\groovy-1.7.2\bin\groovysh Groovy Shell (1.7.2, JVM: 1.6.0_20) Type 'help' or '\h' for help. -------------------------------------------------- groovy:000> GCStats.fullGCCount ===> 0 groovy:000> System.gc() ===> null groovy:000> GCStats.fullGCCount ===> 1 groovy:000> System.gc() ===> null groovy:000> System.gc() ===> null groovy:000> GCStats.fullGCCount ===> 3 groovy:000> GCStats.youngGCCount ===> 9 groovy:000> GCStats.youngGCCount ===> 9 groovy:000> GCStats.youngGCCount ===> 9 groovy:000> System.gc() ===> null groovy:000> GCStats.youngGCCount ===> 9 groovy:000> GCStats.fullGCCount ===> 4 groovy:000> quit
这是在Sun JDK 6 update 20上跑的。顺带一提,如果这是跑在JRockit上的话,那full GC的次数就不会增加——因为JRockit里System.gc()默认是触发young GC的;请不要因为Sun HotSpot的默认行为而认为System.gc()总是会触发full GC的。
关于JMX的MXBean的使用,也可以参考下面两篇文档:
Groovy and JMX
Monitoring the JVM Heap with JRuby
发表评论
-
深入理解JVM
2011-01-21 11:50 6581 Java技术与Java虚拟机 说起Java,人 ... -
JVM调优总结(十二)-参考资料
2011-01-21 11:49 783能整理出上面一些东西,也是因为站在巨人的肩上。下面是一 ... -
JVM调优总结(十)-调优方法
2011-01-21 11:49 661JVM调优工具 Jconsole,jProfile,Vi ... -
JVM调优总结(九)-新一代的垃圾回收算法
2011-01-21 11:48 753垃圾回收的瓶颈 传统分代垃圾回收方式,已经在一定程度 ... -
JVM调优总结(八)-典型配置举例2
2011-01-21 11:47 727常见配置汇总 堆设置 -Xms:初始堆 ... -
JVM调优总结(七)-典型配置举例1
2011-01-21 11:47 740以下配置主要针对分代垃圾回收算法而言。 堆大 ... -
JVM调优总结(六)-分代垃圾回收详述2
2011-01-21 11:46 795分代垃圾回收流程示意 ... -
JVM调优总结(五)-分代垃圾回收详述1
2011-01-21 11:46 618为什么要分代 分代的垃圾回收策略,是基于这样一个事实 ... -
JVM调优总结(四)-垃圾回收面临的问题
2011-01-21 11:45 741如何区分垃圾 上面说到的“引用计数”法,通过统 ... -
JVM调优总结(三)-基本垃圾回收算法
2011-01-21 11:44 677可以从不同的的角 ... -
JVM内存管理:深入垃圾收集器与内存分配策略
2011-01-21 11:43 858Java与C++之间有一堵由内存动态分配和垃圾收集技术所围 ... -
JVM内存管理:深入Java内存区域与OOM
2011-01-21 11:43 593Java与C++之间有一堵由内存动态分配和垃圾收集技 ... -
java线程安全总结
2011-01-21 11:42 619最近想将java基础 ... -
慢慢琢磨JVM——恭喜JavaEye重新开张
2011-01-21 11:40 7211 JVM简介 JVM是我们Javaer的最基本功底了, ... -
JVM 几个重要的参数
2011-01-21 11:37 883<本文提供的设置仅仅是在高压力, 多CPU, 高内存环境 ... -
JVM调优总结(二)-一些概念
2011-01-21 11:36 713Java对象的大小 基 ... -
JVM调优总结(一)-- 一些概念
2011-01-21 11:31 592转:http://www.iteye.com/wiki ...
相关推荐
1. JVM调优 ...3.1 通过Java/JMX得到full GC次数? 3.2 如何更快的启动eclipse 4. JVM基础 4.1 JVM内存管理:深入Java内存区域与OOM 4.2 JVM内存管理:深入垃圾收集器与内存分配策略 4.3 深入理解JVM
Java版 jmx 监控weblogic 生成html
最新的hdfs namenode主备安装文档,详细,命令只需要copy执行即可
java jmx操作示例源码 文章地址:http://blog.csdn.net/mr__fang/article/details/41645377
Zabbix通过JMX方式监控java中间件 Zabbix2.0添加了支持用于监控JMX应用程序的服务进程,称为“Zabbix-Java-gateway”;它是用java写的一个程序。 工作原理: zabbix_server想知道一台主机上的特定的JMX值时,它向...
java jmx agent不安全的配置漏洞如何改进(由浅入深代码范例和详细说明).docx
个人收集整理的学习java JMX的好东西,帮助初学者更好的理解JMX的作用和使用方式。个人认为包括的资料比较全了。
You will find this book to be useful long after new versions of JMX become available because the concepts introduced here are classic applications of management concepts and technologies to the Java ...
原文链接:https://blog.csdn.net/m0_37814112/article/details/118852474?spm=1001.2014.3001.5501 说明:包括jmx_prometheus_javaagent-0.16.1.jar和prometheus-jmx-config.yaml
Hbase和Hadoop JMX监控实战
JVM JMX java
需要的自会需要,介绍没用,亲测可用。 javax.jms包,sun的JMS接口规范包,官方已经不提供了,这里给2分,给大家下载。
Java™ and JMX: Building Manageable Systems By Heather Kreger, Ward Harold, Leigh Williamson Publisher : Addison Wesley Pub Date : December 30, 2002 ISBN : 0-672-32408-3 Pages : 592
代理Java包,用于生成JVM的健康的数据,jmx_prometheus_javaagent-0.12.0.jar
FROM confluentinc/cp-kafka:4.1.0COPY prometheus-exporter/jmx_prometheus_javaagent-0.3.0.jar /usr/share/java/kafka/jmx_prometheus_javaagent-0.3.0.jarCOPY prometheus-expoerter/jmx-exporter.yml /usr/...
java jmx 远程监控
Addison Wesley - Java and JMX (2002).chm
JMX 1.2.1 Reference Implementation(重点) Include com.sun.jdmk.comm.HtmlAdaptorServer class http://www.sun.com/software/jdmk/ Downloads, sun-jdmk-runtime-5.1-b34.2.zip/SUNWjdmk/5.1/lib/jdmkrt.jar
gaelyk-functional-test.zip,为gaelyk功能测试数据存储生成器dsl提供运行时依赖项