`
RednaxelaFX
  • 浏览: 3006460 次
  • 性别: Icon_minigender_1
  • 来自: 海外
社区版块
存档分类
最新评论

用Java获取full GC的次数?(2)

    博客分类:
  • Java
阅读更多
接着上一帖,再谈谈一个Java进程要获取自己的full GC次数的方法,同样是高度平台相关的办法。

大家如果熟悉JDK 6的内建工具,或许已经知道可以通过jstat工具很轻松的从外部得知一个Java进程的GC统计信息,其中就包括了full GC的次数。
假定我们相信jstat的数据是准确的,那么只要跟它从同一来源获取数据就可以保证我们拿到正确的full GC次数信息了。
查看OpenJDK 6中jstat的一个源文件,jdk/src/share/classes/sun/tools/jstat/resources/jstat_options,可以看到jstat -gcutil输出的YGC(young GC)与FGC(full GC)值分别是从下面两个定义而来的:
column {
  header "^YGC^"	/* Young Generation Collections */
  data sun.gc.collector.0.invocations
  align right
  width 6
  format "0"
}
column {
  header "^FGC^"	/* Full Collections */
  data sun.gc.collector.1.invocations
  align right
  width 5
  scale raw
  format "0"
}

也就是说,在Oracle (Sun) HotSpot上,通过jvmstat API,找到名字为 "sun.gc.collector.0.invocations""sun.gc.collector.1.invocations"Monitor对象,我们就可以拿到YGC与FGC对应的值了。别的JVM即便支持该API,Monitor的名字也可能会不同;在Oracle (BEA) JRockit R28上,两者对应的名字分别为 "jrockit.gc.latest.yc.number""jrockit.gc.latest.oc.number"

在底层,HotSpot通过perfData接口来提供这些数据;注册数据的实现在services目录里。

OpenJDK官网上也有一个相关文档:HotSpot Jvmstat Performance Counters

提一下jvmstat文档上说的一个注意点:
引用
The instrumented HotSpot JVM exports a set of instrumentation objects, or counters as they are typically called. The set of counters exported by a JVM is not static, as a JVM may create certain counters only when appropriate arguments are specified on the command line. Furthermore, different versions of a JVM may export very different sets of instrumentation. The names of these counters and the data structures used to represent them are considered private, uncommitted interfaces to the HotSpot JVM. Users should not become dependent on any counter names, particularly those that start with prefixes other than "java.".

也就是说我们最好别依赖这些计数器的名字。不过反正这帖只是介绍些hack的办法而已,不管了 

下面用Groovy代码来演示一下。
使用jvmstat API需要指定vmid,对多数系统上本地Java进程的VMID就是PID。这里正好用上以前一帖介绍的获取进程自己的PID的方式。

import java.lang.management.ManagementFactory
import sun.jvmstat.monitor.*;

class Runtimes {
  static int getOwnPid() {
    def name = ManagementFactory.runtimeMXBean.name
    name[0..<name.indexOf('@')] as int
  }
}

class GCStats {
  // Oracle (Sun) HotSpot
  static final String YOUNG_GC_MONITOR_NAME = 'sun.gc.collector.0.invocations'
  static final String FULL_GC_MONITOR_NAME  = 'sun.gc.collector.1.invocations'
  
  // Oracle (BEA) JRockit
  // static final String YOUNG_GC_MONITOR_NAME = 'jrockit.gc.latest.yc.number'
  // static final String FULL_GC_MONITOR_NAME  = 'jrockit.gc.latest.oc.number'
  
  static final Monitor youngGCMonitor;
  static final Monitor fullGCMonitor;
  
  static {
    def vmId     = new VmIdentifier(Runtimes.ownPid as String)
    def interval = 0
    def monitoredHost = MonitoredHost.getMonitoredHost(vmId)
    def monitoredVm = monitoredHost.getMonitoredVm(vmId, interval)
    youngGCMonitor = monitoredVm.findByName(YOUNG_GC_MONITOR_NAME)
    fullGCMonitor = monitoredVm.findByName(FULL_GC_MONITOR_NAME)
  }
  
  static int getYoungGCCount() {
    youngGCMonitor.value
  }
  
  static int getFullGCCount() {
    fullGCMonitor.value
  }
}

可以看到,要获取young GC与full GC次数的读数很简单,找到合适的Monitor对象后,每次读一下value属性就好了。
在Groovy shell里演示一下使用情况,在Sun JDK 6 update 20/Windows XP SP3上跑:
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(); System.gc(); System.gc()
===> null
groovy:000> GCStats.fullGCCount
===> 4
groovy:000> GCStats.youngGCCount
===> 9
groovy:000> System.gc(); System.gc(); System.gc()
===> null
groovy:000> GCStats.youngGCCount
===> 9
groovy:000> GCStats.fullGCCount
===> 7
groovy:000> quit


这次也顺便演示一下在Oracle JRockit R28/Windows XP SP3上跑:
D:\>\sdk\groovy-1.7.2\bin\groovysh
Groovy Shell (1.7.2, JVM: 1.6.0_17)
Type 'help' or '\h' for help.
--------------------------------------------------
groovy:000> GCStats
===> class GCStats
groovy:000> GCStats.youngGCCount
===> 1
groovy:000> System.gc()
===> null
groovy:000> GCStats.youngGCCount
===> 2
groovy:000> System.gc(); System.gc(); System.gc()
===> null
groovy:000> GCStats.youngGCCount
===> 5
groovy:000> GCStats.fullGCCount
===> 0
groovy:000> quit

可以看到System.gc()引发的是young GC而不是full GC吧? ^_^
分享到:
评论
4 楼 RednaxelaFX 2010-12-04  
IcyFenix 写道
呃,原来你下一篇博客已经写了这个事,刚才没看到 = =#

是上一篇…这个系列的第一篇是写JMX的,这个是第二篇,我正好心情好所以讲点hack的办法 >_<
3 楼 IcyFenix 2010-12-04  
呃,原来你下一篇博客已经写了这个事,刚才没看到 = =#
2 楼 RednaxelaFX 2010-12-04  
那个…上一篇不就是用JMX来获取这种信息的么。另外System.gc()引发的GC种类我也根据具体实现来分开说明了,如果对此有疑问的话欢迎探讨,HotSpot这边我可以把源码找来说明它是触发full GC(或者是完全不引发GC,根据启动参数决定);JRockit是文档上写着引发minor GC的。
1 楼 IcyFenix 2010-12-04  
撒加同学,我觉得取YGC和FGC次数,没有必要引jvmstat的类进来,jvmstat里面也是根据jmx开放的mbean来找gc次数的直接从jmx里面拿还省掉去找自己的pid,和平台也不用咬得那么死。下面的代码以ps/ps old收集器为例子,直接从mbean取gc次数:

package org.fenixsoft.jmx;

import java.lang.management.ManagementFactory;

import javax.management.MBeanServer;
import javax.management.ObjectName;

public class MBeanAccess {
	public static void main(String[] args) throws Exception {
		MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
		ObjectName youngMBean = new ObjectName("java.lang:type=GarbageCollector,name=PS MarkSweep");
		ObjectName tenuredMBean = new ObjectName("java.lang:type=GarbageCollector,name=PS Scavenge");
		System.out.println("YGC:" + mbs.getAttribute(youngMBean, "CollectionCount"));
		System.out.println("FGC:" + mbs.getAttribute(tenuredMBean, "CollectionCount"));
		System.gc();
		System.out.println("YGC:" + mbs.getAttribute(youngMBean, "CollectionCount"));
		System.out.println("FGC:" + mbs.getAttribute(tenuredMBean, "CollectionCount"));
	}
}


另外,System.gc()引发哪种gc这个不是一概而论的吧。

相关推荐

    GCViewer-FullGC分析工具

    GCViewer 能否分析 java 程序 GC 日志,能否图表展示堆内存,年轻代,老年代,永久带以及full gc 的使用情况

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

    GC有两种类型:Scavenge GC(也称Young GC)和Full GC。 一般Full GC时,机器的Load会升高,应用也会停止响应一会(持续长达几秒),如果应用一直频繁的进行FullGC,一方面会出现应用无法提供正常服务,另一方面...

    Java full gc触发情况实例解析

    主要介绍了Java full gc触发情况实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    深入java虚拟机

    1. JVM调优 ...3.1 通过Java/JMX得到full GC次数? 3.2 如何更快的启动eclipse 4. JVM基础 4.1 JVM内存管理:深入Java内存区域与OOM 4.2 JVM内存管理:深入垃圾收集器与内存分配策略 4.3 深入理解JVM

    AviatorEvaluator执行脚本导致Metaspace不足引发频繁 Full GC

    AviatorEvaluator执行脚本导致Metaspace不足引发频繁 Full GC故障机经过 故障机经过 数据分析&特征平台DMP 最近频繁发生Full GC, 引发集群卡顿,导致经常超时,按照常规的方法,肯定是先看GC 日志 2020-02-17T10:17:...

    JVM Full GC 之 MAT工具分析实践-阿沐1

    1.查看当前机器上所有运行的java进程名称与pid(进程编号) 2.显示指定的jvm进程所有的属性设置和配置参数 1.方法一:使用jdk的jmap命令 2.方

    JAVA gc日志分析工具GChisto及CMS GC补丁

    GChisto及CMS GC相应补丁文件,补丁文件未亲测。 This patch adds the following features and improvements when using CMS GC in incremental mode: detecting Full GCs corrected parsing errors when using -XX:...

    poi大量数据读取gc内存溢出解决方案

    poi读取大量数据会造成gc内存溢出的报错,由于垃圾回收机制无法将大量的对象及时的回收,而这些对象又会保存在内存中,会导致内存不够用的情况,这时候我们就需要使用新的方法,读取为cvs即可.此解决方案可支持千万数据的...

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

    jvm-full-gc调优-jvm-full-gc

    一次诡异的full gc查找问题全过程

    主要给大家分享介绍了一次诡异的full gc查找问题全部过程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧啊

    JAVA面试题垃圾收集机制

    当准备要触发一次Young GC时,如果发现统计数据说之前Young GC的平均晋升大小比目前老年代剩余的空间大,则不会触发Young GC而是转为触发Full GC。(通常情况) 如果有永久代的话,在永久代需要分配空间但已经没有...

    成为JavaGC专家(4)

    在第一篇文章成为JavaGC专家PartI—深入浅出Java垃圾回收机制中我们学习了不同GC算法的执行过程,GC如何工作,新生代及老年代的基本概念,在JDK7中你应该了解的5种GC类型以及他们的性能如何。在第二篇文章成为JavaGC...

    Full Stack AngularJS for Java Developers.pdf

    Full Stack AngularJS for Java Developers Build a Full-Featured Web Application from Scratch Using AngularJS with Spring RESTful

    moka7-full-1.0.2.zip_IntByRef_full_java plc_moka7连接效率_谁有moka连接

    连接profinet 的Java库,可连接plc设备

    vnc 4.1.3 src full 带Java资源

    VNC 4.13 src exe java VNC Open Source Code for Windows for Java

    Full Stack AngularJS for Java Developers 无水印原版pdf

    Full Stack AngularJS for Java Developers 英文无水印原版pdf pdf所有页面使用FoxitReader、PDF-XChangeViewer、SumatraPDF和Firefox测试都可以打开 本资源转载自网络,如有侵权,请联系上传者或csdn删除 查看...

    java监控.rar

    FGC:Full gc次数 FGCT:Full gc耗时(秒) GCT:gc总耗时(秒) Loaded:表示载入了类的数量 Unloaded 表示卸载类的数量 Compiled 表示编译任务执行的次数 Failed表示编译失败的次数 total:线程总数 ...

    java堆内存详解.docx

    GC分为两种: Minor GC、Full GC(也叫做Major GC). Minor GC(简称GC) Minor GC是发生在新生代中的垃圾收集动作, 所采用的是复制算法。 GC一般为堆空间某个区发生了垃圾回收, 新生代(Young)几乎是所有java对象...

    JAVA_FULL-Technical Questions and Answers.doc

    JAVA_FULL-Technical Questions and Answers

Global site tag (gtag.js) - Google Analytics