`
millerhu
  • 浏览: 13833 次
  • 性别: Icon_minigender_1
  • 来自: 厦门
最近访客 更多访客>>
社区版块
存档分类
最新评论

通过Java/JMX得到full GC次数?

    博客分类:
  • JVM
阅读更多
今天有个同事问如何能通过JMX获取到某个Java进程的full GC次数:
引用
hi,问个问题,怎们在java中获取到full gc的次数呢?
我现在用jmx的那个得到了gc次数,不过不能细化出来full gc的次数

Java代码 复制代码
  1. for (final GarbageCollectorMXBean garbageCollector   
  2.         : ManagementFactory.getGarbageCollectorMXBeans()) {   
  3.     gcCounts += garbageCollector.getCollectionCount();   
  4. }  
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统计程序:
Groovy代码 复制代码
  1. import java.lang.management.ManagementFactory   
  2.   
  3. printGCStats = {   
  4.   def youngGenCollectorNames = [   
  5.     // Oracle (Sun) HotSpot   
  6.     // -XX:+UseSerialGC   
  7.     'Copy',   
  8.     // -XX:+UseParNewGC   
  9.     'ParNew',   
  10.     // -XX:+UseParallelGC   
  11.     'PS Scavenge',   
  12.        
  13.     // Oracle (BEA) JRockit   
  14.     // -XgcPrio:pausetime   
  15.     'Garbage collection optimized for short pausetimes Young Collector',   
  16.     // -XgcPrio:throughput   
  17.     'Garbage collection optimized for throughput Young Collector',   
  18.     // -XgcPrio:deterministic   
  19.     'Garbage collection optimized for deterministic pausetimes Young Collector'  
  20.   ]   
  21.   
  22.   def oldGenCollectorNames = [   
  23.     // Oracle (Sun) HotSpot   
  24.     // -XX:+UseSerialGC   
  25.     'MarkSweepCompact',   
  26.     // -XX:+UseParallelGC and (-XX:+UseParallelOldGC or -XX:+UseParallelOldGCCompacting)   
  27.     'PS MarkSweep',   
  28.     // -XX:+UseConcMarkSweepGC   
  29.     'ConcurrentMarkSweep',   
  30.        
  31.     // Oracle (BEA) JRockit   
  32.     // -XgcPrio:pausetime   
  33.     'Garbage collection optimized for short pausetimes Old Collector',   
  34.     // -XgcPrio:throughput   
  35.     'Garbage collection optimized for throughput Old Collector',   
  36.     // -XgcPrio:deterministic   
  37.     'Garbage collection optimized for deterministic pausetimes Old Collector'  
  38.   ]   
  39.   
  40.   R: {   
  41.     ManagementFactory.garbageCollectorMXBeans.each {   
  42.       def name  = it.name   
  43.       def count = it.collectionCount   
  44.       def gcType;   
  45.       switch (name) {   
  46.       case youngGenCollectorNames:   
  47.         gcType = 'Minor Collection'  
  48.         break   
  49.       case oldGenCollectorNames:   
  50.         gcType = 'Major Collection'  
  51.         break   
  52.       default:   
  53.         gcType = 'Unknown Collection Type'  
  54.         break   
  55.       }   
  56.       println "$count <- $gcType: $name"  
  57.     }   
  58.   }   
  59. }   
  60.   
  61. 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()

执行可以看到类似这样的输出:
Command prompt代码 复制代码
  1. 5 <- Minor Collection: Copy   
  2. 0 <- Major Collection: MarkSweepCompact  
5 <- Minor Collection: Copy
0 <- Major Collection: MarkSweepCompact

↑这是用client模式的HotSpot执行得到的;
Command prompt代码 复制代码
  1. 0 <- Minor Collection: Garbage collection optimized for throughput Young Collector   
  2. 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程序:
Groovy代码 复制代码
  1. import java.lang.management.ManagementFactory   
  2.   
  3. class GCStats {   
  4.   static final List<String> YoungGenCollectorNames = [   
  5.     // Oracle (Sun) HotSpot   
  6.     // -XX:+UseSerialGC   
  7.     'Copy',   
  8.     // -XX:+UseParNewGC   
  9.     'ParNew',   
  10.     // -XX:+UseParallelGC   
  11.     'PS Scavenge',   
  12.        
  13.     // Oracle (BEA) JRockit   
  14.     // -XgcPrio:pausetime   
  15.     'Garbage collection optimized for short pausetimes Young Collector',   
  16.     // -XgcPrio:throughput   
  17.     'Garbage collection optimized for throughput Young Collector',   
  18.     // -XgcPrio:deterministic   
  19.     'Garbage collection optimized for deterministic pausetimes Young Collector'  
  20.   ]   
  21.      
  22.   static final List<String> OldGenCollectorNames = [   
  23.     // Oracle (Sun) HotSpot   
  24.     // -XX:+UseSerialGC   
  25.     'MarkSweepCompact',   
  26.     // -XX:+UseParallelGC and (-XX:+UseParallelOldGC or -XX:+UseParallelOldGCCompacting)   
  27.     'PS MarkSweep',   
  28.     // -XX:+UseConcMarkSweepGC   
  29.     'ConcurrentMarkSweep',   
  30.        
  31.     // Oracle (BEA) JRockit   
  32.     // -XgcPrio:pausetime   
  33.     'Garbage collection optimized for short pausetimes Old Collector',   
  34.     // -XgcPrio:throughput   
  35.     'Garbage collection optimized for throughput Old Collector',   
  36.     // -XgcPrio:deterministic   
  37.     'Garbage collection optimized for deterministic pausetimes Old Collector'  
  38.   ]   
  39.      
  40.   static int getYoungGCCount() {   
  41.     ManagementFactory.garbageCollectorMXBeans.inject(0) { youngGCCount, gc ->   
  42.       if (YoungGenCollectorNames.contains(gc.name))   
  43.         youngGCCount + gc.collectionCount   
  44.       else   
  45.         youngGCCount   
  46.     }   
  47.   }   
  48.      
  49.   static int getFullGCCount() {   
  50.     ManagementFactory.garbageCollectorMXBeans.inject(0) { fullGCCount, gc ->   
  51.       if (OldGenCollectorNames.contains(gc.name))   
  52.         fullGCCount + gc.collectionCount   
  53.       else   
  54.         fullGCCount   
  55.     }   
  56.   }   
  57. }  
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
    }
  }
}

用的时候:
Groovysh代码 复制代码
  1. D:\>\sdk\groovy-1.7.2\bin\groovysh   
  2. Groovy Shell (1.7.2, JVM: 1.6.0_20)   
  3. Type 'help' or '\h' for help.   
  4. --------------------------------------------------   
  5. groovy:000> GCStats.fullGCCount   
  6. ===> 0  
  7. groovy:000> System.gc()   
  8. ===> null   
  9. groovy:000> GCStats.fullGCCount   
  10. ===> 1  
  11. groovy:000> System.gc()   
  12. ===> null   
  13. groovy:000> System.gc()   
  14. ===> null   
  15. groovy:000> GCStats.fullGCCount   
  16. ===> 3  
  17. groovy:000> GCStats.youngGCCount   
  18. ===> 9  
  19. groovy:000> GCStats.youngGCCount   
  20. ===> 9  
  21. groovy:000> GCStats.youngGCCount   
  22. ===> 9  
  23. groovy:000> System.gc()   
  24. ===> null   
  25. groovy:000> GCStats.youngGCCount   
  26. ===> 9  
  27. groovy:000> GCStats.fullGCCount   
  28. ===> 4  
  29. 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
分享到:
评论

相关推荐

    java应用JVM的GC频率观察方法

    例如,JConsole也是JDK自带的监控工具,通过JMX接口可以远程连接到Java应用,展示包括GC在内的各种性能指标。GCMonitor是一个轻量级的监控框架,可以直接集成到应用中,以低侵入性的方式监控GC状态。 监控GC频率的...

    FullGC的样例报告

    首先,我们关注"元空间不足导致频繁FullGC.pdf"这个文件。元空间是Java 8引入的新特性,取代了之前的永久代(Permanent Generation)。元空间主要存储类的元数据,如类信息、方法信息、字段信息等。当元空间满时,...

    jvm-full-gc调优-jvm-full-gc.zip

    在Java开发中,JVM(Java虚拟机)的性能优化是一项关键任务,特别是对于大型系统而言,频繁的Full GC(垃圾收集)会导致应用暂停时间过长,影响用户体验。本资料"jvm-full-gc调优-jvm-full-gc.zip"显然是针对如何...

    jvm-full-gc.zip

    为了更好地理解和调优Full GC,我们可以借助JDK自带的JConsole、VisualVM、JFR(Java Flight Recorder)以及JMX等工具进行监控。它们能提供详细的GC日志,帮助我们分析Full GC的触发原因和性能瓶颈。 总结,理解JVM...

    Java 内存区域和GC机制

    - **GC类型**:主要分为Minor GC(年轻代GC)、Major GC(老年代GC)和Full GC(全局GC)。 - **GC策略**:包括复制算法、标记-清除算法、标记-整理算法、分代收集策略等,根据JVM版本和配置不同而有所不同。 - *...

    java gc调优

    4. **减少Full GC**:频繁的Full GC会导致长时间的停顿,优化对象分配和存活率以减少触发Full GC的次数。 5. **识别内存泄漏**:分析GC日志,查找可能导致内存泄漏的对象。 6. **使用对象池**:对于生命周期短且创建...

    GC基本调优工具介绍

    在Java世界中,垃圾收集(Garbage Collection, GC)是管理内存的重要机制,它自动回收不再使用的对象,防止内存泄漏。然而,随着应用规模的扩大和复杂度的增加,理解和优化GC行为变得至关重要。本篇文章将详细介绍...

    Java GC笔记总纲1

    Java垃圾收集(GC)是Java编程中至关重要的一个部分,它自动管理程序的内存,以避免内存泄漏和系统资源耗尽。以下是对标题和描述中提及的知识点的详细阐述: ### 1. 基础知识 #### 1.1 常见的内存溢出 内存溢出是...

    VisualGC(监控程序性能调优)

    5. **JMX支持**:通过JMX(Java Management Extensions)连接到远程应用,进行远程监控和管理。 6. **采样分析**:定期采样线程堆栈,展示程序的执行路径。 7. **本地及远程连接**:不仅可以分析本地运行的应用,还...

    Visual GC(监控垃圾回收器)

    3. **GC活动**:详细记录每一次GC事件,包括Minor GC、Major GC和Full GC,以及它们的耗时,帮助开发者识别是否存在频繁GC或长时间停顿的问题。 4. **线程状态**:展示所有运行中的线程,包括它们的状态(如运行、...

    JVM体系结构与GC调优

    通过深入学习JVM体系结构和GC调优,开发者可以更好地理解和控制Java应用的内存使用,减少垃圾收集的开销,提升系统性能。这份PPT将帮助我们系统地掌握这些关键点,使我们能够应对实际开发中的各种挑战。

    实战Hot Spot JVM GC

    在GC监控方面,除了使用JMX参数外,还可以使用-Xloggc:文件参数来记录GC日志,并通过-XX:+PrintGCDetails等参数打印GC的详细信息。 优化建议包括合理设置堆内存大小,选择合适的垃圾回收器,调整新生代与老年代的...

    Java工程师成神之路~-HollisChuang's Blog1

    例如,通过分析GC日志找出Full GC的原因,或者使用Eclipse Memory Analyzer Tool(MAT)来分析堆dump文件,识别内存泄漏。对于不同的内存溢出问题,我们需要采取不同的策略,如增大堆内存、调整年轻代和老年代的大小...

    java jvm-old gc耗时几十s,导致系统告警(csdn)————程序.pdf

    在Java应用程序中,JVM(Java虚拟机)的垃圾收集(Garbage Collection, GC)是自动管理内存的关键机制。当对象不再被引用时,GC负责回收这些无用的对象所占用的内存空间,以避免内存泄漏。然而,如果GC过程耗时过长...

    Java虚拟机(第二版)

    特别是GC(Garbage Collection)算法,如Minor GC、Major GC和Full GC的运作机制,以及如何调整GC参数以优化性能。 再者,JVM的调优是提升Java应用性能的重要手段。这可能涉及堆大小设置、栈空间分配、方法区配置、...

    实战JAVA虚拟机 JVM故障诊断与性能优化

    例如,通过合理设置堆大小、新生代和老年代的比例,可以减少Full GC的发生;通过使用并发标记扫描GC,提高垃圾回收效率;通过分析线程Dump,找出CPU消耗高的线程进行优化;编写高效且无冗余的Java代码,减少不必要的...

    preformance.rar

    了解如何使用JMX、VisualVM等工具进行GC监控和调优,是提升Java应用性能的重要手段。 以上内容涵盖了Apache服务器的配置、JVM内存管理、垃圾收集机制以及性能调优等多个方面,对于深入理解和优化Java应用的性能具有...

    java性能优化教程

    例如,调整-Xms和-Xmx设置合适的堆内存大小,防止频繁的Full GC。使用-XX:+UseG1GC选择更高效的垃圾回收器。开启-XX:+UseStringDeduplication减少字符串占用的内存。 监控和分析工具的使用能帮助我们定位性能问题。...

    Java工程师应用技术汇总

    - **频繁FullGC的解决**:调整年轻代和年老代的比例,减少对象的晋升速度。 - **OutOfMemory处理**:分析堆转储文件,找出内存泄漏的原因。 - **日志分析**:使用VisualVM等工具分析垃圾回收日志。 **1.1.7 参考...

Global site tag (gtag.js) - Google Analytics