- 浏览: 3047829 次
- 性别:
- 来自: 海外
文章分类
- 全部博客 (430)
- Programming Languages (23)
- Compiler (20)
- Virtual Machine (57)
- Garbage Collection (4)
- HotSpot VM (26)
- Mono (2)
- SSCLI Rotor (1)
- Harmony (0)
- DLR (19)
- Ruby (28)
- C# (38)
- F# (3)
- Haskell (0)
- Scheme (1)
- Regular Expression (5)
- Python (4)
- ECMAScript (2)
- JavaScript (18)
- ActionScript (7)
- Squirrel (2)
- C (6)
- C++ (10)
- D (2)
- .NET (13)
- Java (86)
- Scala (1)
- Groovy (3)
- Optimization (6)
- Data Structure and Algorithm (3)
- Books (4)
- WPF (1)
- Game Engines (7)
- 吉里吉里 (12)
- UML (1)
- Reverse Engineering (11)
- NSIS (4)
- Utilities (3)
- Design Patterns (1)
- Visual Studio (9)
- Windows 7 (3)
- x86 Assembler (1)
- Android (2)
- School Assignment / Test (6)
- Anti-virus (1)
- REST (1)
- Profiling (1)
- misc (39)
- NetOA (12)
- rant (6)
- anime (5)
- Links (12)
- CLR (7)
- GC (1)
- OpenJDK (2)
- JVM (4)
- KVM (0)
- Rhino (1)
- LINQ (2)
- JScript (0)
- Nashorn (0)
- Dalvik (1)
- DTrace (0)
- LLVM (0)
- MSIL (0)
最新评论
-
mldxs:
虽然很多还是看不懂,写的很好!
虚拟机随谈(一):解释器,树遍历解释器,基于栈与基于寄存器,大杂烩 -
HanyuKing:
Java的多维数组 -
funnyone:
Java 8的default method与method resolution -
ljs_nogard:
Xamarin workbook - .Net Core 中不 ...
LINQ的恶搞…… -
txm119161336:
allocatestlye1 顺序为 // Fields o ...
最近做的两次Java/JVM分享的概要
接着上一帖,再谈谈一个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)值分别是从下面两个定义而来的:
也就是说,在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文档上说的一个注意点:
也就是说我们最好别依赖这些计数器的名字。不过反正这帖只是介绍些hack的办法而已,不管了
下面用Groovy代码来演示一下。
使用jvmstat API需要指定vmid,对多数系统上本地Java进程的VMID就是PID。这里正好用上以前一帖介绍的获取进程自己的PID的方式。
可以看到,要获取young GC与full GC次数的读数很简单,找到合适的Monitor对象后,每次读一下value属性就好了。
在Groovy shell里演示一下使用情况,在Sun JDK 6 update 20/Windows XP SP3上跑:
这次也顺便演示一下在Oracle JRockit R28/Windows XP SP3上跑:
可以看到System.gc()引发的是young GC而不是full GC吧? ^_^
是上一篇…这个系列的第一篇是写JMX的,这个是第二篇,我正好心情好所以讲点hack的办法 >_<
大家如果熟悉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次数:
另外,System.gc()引发哪种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这个不是一概而论的吧。
发表评论
-
The Prehistory of Java, HotSpot and Train
2014-06-02 08:18 0http://cs.gmu.edu/cne/itcore/vi ... -
MSJVM and Sun 1.0.x/1.1.x
2014-05-20 18:50 0当年的survey paper: http://www.sym ... -
Sun JDK1.4.2_28有TieredCompilation
2014-05-12 08:48 0原来以前Sun的JDK 1.4.2 update 28就已经有 ... -
IBM JVM notes (2014 ver)
2014-05-11 07:16 0Sovereign JIT http://publib.bou ... -
class data sharing by Apple
2014-03-28 05:17 0class data sharing is implement ... -
Java 8与静态工具类
2014-03-19 08:43 16273以前要在Java里实现所谓“静态工具类”(static uti ... -
Java 8的default method与method resolution
2014-03-19 02:23 10450先看看下面这个代码例子, interface IFoo { ... -
HotSpot Server VM与Server Class Machine
2014-02-18 13:21 0HotSpot VM历来有Client VM与Server V ... -
Java 8的lambda表达式在OpenJDK8中的实现
2014-02-04 12:08 0三月份JDK8就要发布首发了,现在JDK8 release c ... -
GC stack map与deopt stack map的异同
2014-01-08 09:56 0两者之间不并存在包含关系。它们有交集,但也各自有特别的地方。 ... -
HotSpot Server Compiler与data-flow analysis
2014-01-07 17:41 0http://en.wikipedia.org/wiki/Da ... -
字符串的一般封装方式的内存布局 (1): 元数据与字符串内容,整体还是分离?
2013-11-07 17:44 22390(Disclaimer:未经许可请 ... -
字符串的一般封装方式的内存布局
2013-11-01 12:55 0(Disclaimer:未经许可请 ... -
关于string,内存布局,C++ std::string,CoW
2013-10-30 20:45 0(Disclaimer:未经许可请 ... -
对C语义的for循环的基本代码生成模式
2013-10-19 23:12 21871之前有同学在做龙书(第二版)题目,做到8.4的练习,跟我对答案 ... -
Java的instanceof是如何实现的
2013-09-22 16:57 0Java语言规范,Java SE 7版 http://docs ... -
oop、klass、handle的关系
2013-07-30 17:34 0oopDesc及其子类的实例 oop : oopDesc* ... -
Nashorn各种笔记
2013-07-15 17:03 0http://bits.netbeans.org/netbea ... -
《深入理解Java虚拟机(第二版)》书评
2013-07-08 19:19 0值得推荐的中文Java虚拟机入门书 感谢作者赠与的样书,以下 ... -
豆列:从表到里学习JVM实现
2013-06-13 14:13 48359刚写了个学习JVM用的豆列跟大家分享。 豆列地址:http: ...
相关推荐
此外,可以使用`-Xloggc:gc.log`指定日志输出文件,然后通过工具如GCViewer进行日志分析,以获取更直观的GC行为可视化。 2. 在生产环境下,由于直接修改JVM参数可能影响线上服务,因此通常推荐使用专门的监控工具。...
3. **统计信息**:提供详细的统计信息,如平均GC时间、总GC次数、暂停时间等,帮助量化评估系统性能。 4. **自定义配置**:用户可以根据需求自定义日志解析规则,适应不同JVM配置下的日志格式。 四、使用步骤 1. **...
2. **Young GC次数**:年轻代GC是指只清理新生代(New Generation)内存区域的GC。新生代通常包含最近创建的对象,频繁进行小规模的GC以保持这部分内存的高效利用。 3. **Full GC次数**:全GC涉及整个堆(包括...
分别对年轻代(Minor GC)、老年代(Full GC)的GC活动进行了单独分析,包括GC次数、回收字节数、总耗时、平均耗时以及最小/最大耗时。 通过对这些数据的深入分析,可以识别出Java应用程序中的内存使用模式、垃圾...
2. **获取GC日志**: 首先确保Java应用配置了生成GC日志,通常在JVM启动参数中添加`-XX:+PrintGC`和`-XX:+PrintGCDetails`选项。 3. **运行GChisto**: 在解压后的目录中,双击`GChisto.jar`文件,启动工具。 4. **...
这些工具可以帮助开发者监控JVM的运行状态,包括GC的次数和时间、内存使用情况等。 jstat命令提供了一个强大的工具用于监控Java虚拟机中的堆使用情况和GC的状态。使用例如"-gccapacity"、"-gccause"、"-gcutil"等...
元空间的大小可以动态调整,避免了永久代因空间不足导致的Full GC问题。 6. **G1垃圾收集器与动态编译**: G1垃圾收集器是Java 9默认的垃圾收集器,它在进行垃圾回收时,会考虑JIT编译的影响,避免在编译过程中...
此外,还有详细的统计信息,如总GC次数、平均GC耗时等,这些数据对于调优是非常有价值的。 GCLogViewer还支持比较不同时间段或不同环境下的GC日志,这样可以对比分析不同配置或优化策略对GC行为的影响。通过这种...
2. Java虚拟机栈:存放基本数据类型、对象引用和方法出口,也是线程私有。 3. Native方法栈:服务于Native方法,与虚拟机栈类似,线程私有。 4. Java堆:存储所有对象实例和数组,是Java内存中最大的一块,也是垃圾...
- 以下哪些情况会产生Full GC:**持久代被写满**和**显式调用System.gc()**(D正确,年轻代和年老代被写满会导致Minor GC和Major GC,而不是Full GC)。 - Checked Exception包括**ClassNotFoundException**和**...
- **Full GC次数**:频繁的Full GC会导致应用暂停时间过长。 - **线程状态**:分析阻塞、等待和死锁等问题。 - **类加载情况**:过多的类加载可能占用大量内存。 6. **调优策略**: - **根据应用特点选择合适的...
- **Full GC**: 在老年代空间不足或系统检测到内存压力较大时触发,涉及整个堆空间及方法区的垃圾回收。 - **GC调优**: 通过调整新生代和老年代的比例来优化性能。默认比例为1:2,可以通过参数调整以适应不同的...
- **FGC/FGCT**: Full GC的次数与总时间。 - **GCT**: 总的GC时间。 - **`jstat -gc <vmid>`**: 显示GC统计信息。 - **S0C/S1C**: 第一个/第二个Survivor Space的大小。 - **S0U/S1U**: 第一个/第二个Survivor...
1.JVM的gc概述 gc即垃圾收集机制是指jvm用于释放那些不再使用的对象所占用的内存。java语言并不要求jvm有gc,也没有规定gc如何工作。...一般的标准是减少fullgc的次数,最好硬件支持使用并行垃圾回收(要求多CPU)。
- `FGC`:从应用程序启动到采样时发生Full GC的次数。 - `FGCT`:从应用程序启动到采样时Full GC所用的时间(单位秒)。 - `GCT`:从应用程序启动到采样时用于垃圾回收的总时间(单位秒)。 ##### 2. 关注指标 -...
- **Minor GC、Major GC、Full GC**:分别表示年轻代、老年代、整个堆的垃圾回收。 - **类文件结构**:包括魔数、版本号、常量池等部分。 - **User user = new User()做了什么操作**:分配内存、初始化对象等。 - **...
- Full GC:全堆垃圾回收,涉及年轻代和老年代,通常较慢。 9. 对象分配: - 年轻代是默认分配区域,但如果年轻代空间不足,大对象或经过多次晋升的对象会直接分配在老年代。 10. 不同的垃圾收集器: - Serial...