`
ol_beta
  • 浏览: 290351 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

[转载]理解 CMS GC 日志

阅读更多

CMS GC with -XX:+PrintGCDetails and -XX:+PrintGCTimeStamps prints a lot of information. Understanding this information can help in fine tuning various parameters of the application and CMS to achieve best performance.

Let's have a look at some of the CMS logs generated with 1.4.2_10:

39.910: [GC 39.910: [ParNew: 261760K->0K(261952K), 0.2314667 secs] 262017K->26386K(1048384K), 0.2318679 secs]

Young generation (ParNew) collection. Young generation capacity is 261952K and after the collection its occupancy drops down from 261760K to 0. This collection took 0.2318679 secs.

40.146: [GC [1 CMS-initial-mark: 26386K(786432K)] 26404K(1048384K), 0.0074495 secs]

Beginning of tenured generation collection with CMS collector. This is initial Marking phase of CMS where all the objects directly reachable from roots are marked and this is done with all the mutator threads stopped.

Capacity of tenured generation space is 786432K and CMS was triggered at the occupancy of 26386K.

40.154: [CMS-concurrent-mark-start]

Start of concurrent marking phase.
In Concurrent Marking phase, threads stopped in the first phase are started again and all the objects transitively reachable from the objects marked in first phase are marked here.

40.683: [CMS-concurrent-mark: 0.521/0.529 secs]

Concurrent marking took total 0.521 seconds cpu time and 0.529 seconds wall time that includes the yield to other threads also.

40.683: [CMS-concurrent-preclean-start]

Start of precleaning.
Precleaning is also a concurrent phase. Here in this phase we look at the objects in CMS heap which got updated by promotions from young generation or new allocations or got updated by mutators while we were doing the concurrent marking in the previous concurrent marking phase. By rescanning those objects concurrently, the precleaning phase helps reduce the work in the next stop-the-world “remark” phase.

40.701: [CMS-concurrent-preclean: 0.017/0.018 secs]

Concurrent precleaning took 0.017 secs total cpu time and 0.018 wall time.

40.704: [GC40.704: [Rescan (parallel) , 0.1790103 secs]40.883: [weak refs processing, 0.0100966 secs] [1 CMS-remark: 26386K(786432K)] 52644K(1048384K), 0.1897792 secs]

Stop-the-world phase. This phase rescans any residual updated objects in CMS heap, retraces from the roots and also processes Reference objects. Here the rescanning work took 0.1790103 secs and weak reference objects processing took 0.0100966 secs. This phase took total 0.1897792 secs to complete.

40.894: [CMS-concurrent-sweep-start]

Start of sweeping of dead/non-marked objects. Sweeping is concurrent phase performed with all other threads running.

41.020: [CMS-concurrent-sweep: 0.126/0.126 secs]

Sweeping took 0.126 secs.

41.020: [CMS-concurrent-reset-start]

Start of reset.

41.147: [CMS-concurrent-reset: 0.127/0.127 secs]

In this phase, the CMS data structures are reinitialized so that a new cycle may begin at a later time. In this case, it took 0.127 secs.

This was how a normal CMS cycle runs. Now let us look at some other CMS log entries:

197.976: [GC 197.976: [ParNew: 260872K->260872K(261952K), 0.0000688 secs]197.976: [CMS197.981: [CMS-concurrent-sweep: 0.516/0.531 secs]
(concurrent mode failure): 402978K->248977K(786432K), 2.3728734 secs] 663850K->248977K(1048384K), 2.3733725 secs]

This shows that a ParNew collection was requested, but it was not attempted because it was estimated that there was not enough space in the CMS generation to promote the worst case surviving young generation objects. We name this failure as “full promotion guarantee failure”.

Due to this, Concurrent Mode of CMS is interrupted and a Full GC is invoked at 197.981. This mark-sweep-compact stop-the-world Full GC took 2.3733725 secs and the CMS generation space occupancy dropped from 402978K to 248977K.

The concurrent mode failure can either be avoided by increasing the tenured generation size or initiating the CMS collection at a lesser heap occupancy by setting CMSInitiatingOccupancyFraction to a lower value and setting UseCMSInitiatingOccupancyOnly to true. The value for CMSInitiatingOccupancyFraction should be chosen appropriately because setting it to a very low value will result in too frequent CMS collections.

Sometimes we see these promotion failures even when the logs show that there is enough free space in tenured generation. The reason is 'fragmentation' - the free space available in tenured generation is not contiguous, and promotions from young generation require a contiguous free block to be available in tenured generation. CMS collector is a non-compacting collector, so can cause fragmentation of space for some type of applications. In his blog, Jon talks in detail on how to deal with this fragmentation problem:
http://blogs.sun.com/roller/page/jonthecollector?entry=when_the_sum_of_the

Starting with 1.5, for the CMS collector, the promotion guarantee check is done differently. Instead of assuming that the promotions would be worst case i.e. all of the surviving young generation objects would get promoted into old gen, the expected promotion is estimated based on recent history of promotions. This estimation is usually much smaller than the worst case promotion and hence requires less free space to be available in old generation. And if the promotion in a scavenge attempt fails, then the young generation is left in a consistent state and a stop-the-world mark-compact collection is invoked. To get the same functionality with UseSerialGC you need to explicitly specify the switch -XX:+HandlePromotionFailure.

283.736: [Full GC 283.736: [ParNew: 261599K->261599K(261952K), 0.0000615 secs] 826554K->826554K(1048384K), 0.0003259 secs]
GC locker: Trying a full collection because scavenge failed
283.736: [Full GC 283.736: [ParNew: 261599K->261599K(261952K), 0.0000288 secs]

Stop-the-world GC happening when a JNI Critical section is released. Here again the young generation collection failed due to “full promotion guarantee failure” and then the Full GC is being invoked.

CMS can also be run in incremental mode (i-cms), enabled with -XX:+CMSIncrementalMode. In this mode, CMS collector does not hold the processor for the entire long concurrent phases but periodically stops them and yields the processor back to other threads in application. It divides the work to be done in concurrent phases in small chunks(called duty cycle) and schedules them between minor collections. This is very useful for applications that need low pause times and are run on machines with small number of processors.

Some logs showing the incremental CMS.

2803.125: [GC 2803.125: [ParNew: 408832K->0K(409216K), 0.5371950 secs] 611130K->206985K(1048192K) icms_dc=4 , 0.5373720 secs]
2824.209: [GC 2824.209: [ParNew: 408832K->0K(409216K), 0.6755540 secs] 615806K->211897K(1048192K) icms_dc=4 , 0.6757740 secs]

Here, the scavenges took respectively 537 ms and 675 ms. In between these two scavenges, iCMS ran for a brief period as indicated by the icms_dc value, which indicates a duty-cycle. In this case the duty cycle was 4%. A simple calculation shows that the iCMS incremental step lasted for 4/100 \* (2824.209 - 2803.125 - 0.537) = 821 ms, i.e. 4% of the time between the two scavenges.

Starting with 1.5, CMS has one more phase – concurrent abortable preclean. Abortable preclean is run between a 'concurrent preclean' and 'remark' until we have the desired occupancy in eden. This phase is added to help schedule the 'remark' phase so as to avoid back-to-back pauses for a scavenge closely followed by a CMS remark pause. In order to maximally separate a scavenge from a CMS remark pause, we attempt to schedule the CMS remark pause roughly mid-way between scavenges.

There is a second reason why we do this. Immediately following a scavenge there are likely a large number of grey objects that need rescanning. The abortable preclean phase tries to deal with such newly grey objects thus reducing a subsequent CMS remark pause.

The scheduling of 'remark' phase can be controlled by two jvm options CMSScheduleRemarkEdenSizeThreshold and CMSScheduleRemarkEdenPenetration. The defaults for these are 2m and 50% respectively. The first parameter determines the Eden size below which no attempt is made to schedule the CMS remark pause because the pay off is expected to be minuscule. The second parameter indicates the Eden occupancy at which a CMS remark is attempted.

After 'concurrent preclean' if the Eden occupancy is above CMSScheduleRemarkEdenSizeThreshold, we start 'concurrent abortable preclean' and continue precleanig until we have CMSScheduleRemarkEdenPenetration percentage occupancy in eden, otherwise we schedule 'remark' phase immediately.

7688.150: [CMS-concurrent-preclean-start]
7688.186: [CMS-concurrent-preclean: 0.034/0.035 secs]
7688.186: [CMS-concurrent-abortable-preclean-start]
7688.465: [GC 7688.465: [ParNew: 1040940K->1464K(1044544K), 0.0165840 secs] 1343593K->304365K(2093120K), 0.0167509 secs]
7690.093: [CMS-concurrent-abortable-preclean: 1.012/1.907 secs]
7690.095: [GC[YG occupancy: 522484 K (1044544 K)]7690.095: [Rescan (parallel) , 0.3665541 secs]7690.462: [weak refs processing, 0.0003850 secs] [1 CMS-remark: 302901K(1048576K)] 825385K(2093120K), 0.3670690 secs]

In the above log, after a preclean, 'abortable preclean' starts. After the young generation collection, the young gen occupancy drops down from 1040940K to 1464K. When young gen occupancy reaches 522484K which is 50% of the total capacity, precleaning is aborted and 'remark' phase is started.

Note that in 1.5, young generation occupancy also gets printed in the final remark phase.

For more detailed information and tips on GC tuning, please refer to the following documents:
http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html
http://java.sun.com/docs/hotspot/gc1.4.2/

官方地址:

http://blogs.oracle.com/poonam/entry/understanding_cms_gc_logs

分享到:
评论

相关推荐

    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:...

    jvmgc日志分析工具

    GC日志分析工具是用来理解和优化JVM内存管理的重要工具。"jvmgc日志分析工具"专为解析和可视化JVM生成的GC日志而设计,帮助开发者识别内存瓶颈,调整内存设置,以及诊断可能的性能问题。 GC日志是JVM在运行过程中...

    GChisto GC日志分析工具

    GC日志是理解和优化Java应用程序内存管理的关键,它记录了垃圾收集器运行的详细信息。`GChisto`是一款专门用于分析GC日志的离线工具,虽然其官网可能已经不可访问,但通过搜索引擎如百度,仍可以找到相关的资源和...

    ga16.zip-分析GC日志native_stderr.log(可分析WAS6.1版本)

    3. **日志模式与指标**:理解不同GC日志模式,如CMS、Parallel、G1等,关注关键指标如吞吐量、暂停时间和内存利用率。 **WAS6.1的配置调整:** 要优化WAS6.1的GC行为,可能需要修改JVM启动参数,如: 1. `-XX:+...

    gcviewer.rar

    1. **日志解析**:GCViewer能够读取JVM生成的标准GC日志格式,并将其转化为易于理解的图表,这些日志通常通过`-Xlog:gc*`或`-XX:+PrintGCDetails`等JVM参数启用。 2. **实时监控**:用户可以实时观察到应用程序的...

    深入理解JVM & G1 GC

    《深入理解JVM & G1 GC》这篇文章和相关压缩包文件主要聚焦于Java虚拟机(JVM)的内存管理,特别是垃圾收集器(GC)的优化,特别是G1(Garbage-First)垃圾收集器的深度解析。下面将详细阐述JVM、GC的基本概念,...

    GChisto和gcviewer

    GC日志分析工具则可以帮助开发者理解JVM内部的垃圾回收行为,优化应用程序性能。GChisto和GCViewer是两个常用的Java GC日志分析工具,它们能够提供深入的洞察力,帮助我们识别潜在的内存泄漏问题,调整垃圾收集器...

    gcviewer-1.37-SNAPSHOT.jar

    用于分析 java gc日志文件。根据日志中的CMS GC统计信息可得到Full GC(也可以理解为Major GC)以及Minor GC相关数据

    Java理解CMS收集器.pdf

    《Java理解CMS收集器》 CMS(Concurrent Mark Sweep)收集器是Java虚拟机中的一种垃圾收集器,主要针对老年代的内存回收,其特点是并发和低停顿。CMS收集器的主要目标是在尽可能短的时间内完成垃圾收集,减少应用...

    gcviewer-1.29-bin.zip

    进一步分析GC日志,GCViewer可以帮助我们理解以下关键概念: 1. **年轻代和老年代**:Java对象在内存中的生命周期分为新生代和老年代,GCViewer可以展示这两个区域的动态变化,帮助我们调整新生代和老年代的大小。 ...

    GCViewer,Tagtraum Industries的GCviewer之叉。tagtraum在2008年停止了开发,我的目标是改进对sun/oracle的java 1.6+垃圾收集器日志(包括g1收集器)的支持。.zip

    然后,将生成的GC日志文件导入到GCViewer,工具会自动解析并生成相应的图表。 在分析过程中,你可以关注以下几个关键指标: 1. **GC暂停时间**:长时间的GC暂停可能会影响应用的响应速度,尤其是对于低延迟的应用...

    gcviewer134.zip

    1. **日志解析**:GCViewer能够解析各种格式的GC日志,包括Sun/Oracle JVM、IBM JVM以及OpenJ9等产生的日志,支持G1、Parallel、CMS、Serial等多种GC算法的日志。 2. **实时可视化**:工具将日志中的数据转化为实时...

    gcviewer-1.33

    总之,GCViewer 1.33是Java开发者诊断和优化内存管理的重要工具,它将复杂的GC日志转化为易读的图形,帮助我们更好地理解并优化Java应用的性能。掌握并运用GCViewer,可以有效提升我们的开发效率,确保系统的高效...

    GCviewer-1.35 GC分析工具

    3. **运行与分析**:双击RUN.bat执行文件,GCviewer将读取指定的GC日志文件,并实时展示分析结果。你可以通过界面观察GC行为,调整视图以查看不同维度的数据。 4. **导出报告**:除了实时查看,GCviewer还支持导出...

    EdwardLee03#issue-case#万恶的swap(CMS GC的remark耗时好几秒)1

    【现象】悲催的是运行了几天后,突然有几台机器开始报警,上机器看到的现象是CMS GC的remark竟然花了20s+,而实际上这个时候old也就用了2g+,这个时

    6.1.5.JVM终结篇笔记1

    【标题】:“6.1.5.JVM终结篇笔记1”主要探讨了JVM的深入理解和垃圾收集(GC)优化,包括GC发生时机、实验环境准备、GC日志及其分析。 【描述】:本笔记首先从宏观角度重新认识JVM,强调了JVM的物理结构,特别是...

    分析gclog的程序

    例如,`-XX:+PrintGC`开启GC日志,`-XX:GCLogFilePath`指定日志文件位置,`-XX:+PrintGCDetails`则会提供更详细的日志信息。 6. **调优策略**:根据`gclog`分析结果,开发者可能需要调整JVM的垃圾收集策略,例如...

    GC基本调优工具介绍

    8. **GC日志分析**:通过设置JVM参数,我们可以开启GC日志,然后使用第三方工具(如GCMV,GcViewer)对日志进行分析,了解GC的运行模式和问题。 在进行GC调优时,通常需要关注以下几个关键指标: - **Full GC频率**...

    2004-11-GC程序员考试题.rar_gc_程序员考试

    5. **GC日志分析**:学习如何解读GC日志,从中获取优化线索,判断是否存在性能问题。 6. **JVM参数调优**:熟悉常用的JVM参数,如-Xms、-Xmx、-XX:NewRatio、-XX:+UseConcMarkSweepGC等,了解如何根据应用需求调整...

Global site tag (gtag.js) - Google Analytics