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

Garbage First(G1) 日志分析工具

阅读更多

G1介绍:http://softbeta.iteye.com/blog/1562185

用python写的一个分析G1日志工具,现在还不是很完善,有时间继续改进:

目前只支持以下配置输出的GC日志:

-XX:+UseG1GC
-XX:+PrintGCDateStamps
-XX:+PrintGCDetails
-Xloggc:/Users/lichengwu/tmp/mtct/mtct_g1.log

 下面是代码:

# coding=utf-8
__author__ = 'lichengwu'
 
import datetime
import re
 
 
'''
Garbage First Log Analyse Util
'''
 
class G1LogUtil:
    __path = ''
    # some regular expression pattern
    # like this '2012-12-19T10:25:19'
    __START_LINE_PATTERN = re.compile('^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:')
    # like this '112M(112M)->0B(112M)'
    __MEMORY_INFO_PATTERN = re.compile('(\d+)([M|B|K|G])\((\d+)([M|B|K|G])\)->(\d+)([M|B|K|G])\((\d+)([M|B|K|G])\)')
    # like this '16M->16M'
    __SIMPLE_MEMORY_INFO_PATTERN = re.compile('(\d+)([M|B|K|G])->(\d+)([M|B|K|G])')
 
    # constructor
    def __init__(self, path):
        self.__path = path
 
 
    """
    analyse G1 log for java
    """
 
    def analyse(self):
        # get log reader
        reader = self.__reader(self.__path)
        # number of GC times
        gc_count = 0
        gc_count_young = 0
        gc_count_mixed = 0
        # total stop the world time
        total_stop_time = 0.000000
        # max heap size
        max_heap_size = 0
        # min heap size
        min_heap_size = 0xEFFFFFFFFFFFFFFFF
        # max eden size
        max_eden_size = 0
        # min eden size
        min_eden_size = 0xEFFFFFFFFFFFFFFFF
        # survivor size
        survivor_size = None
        # total eden size for statistics
        total_eden_size = 0
        # map store memory info
        memory_usage_map = {'young_garbage_percent': [], 'heap_garbage_percent': [], 'young_usage_percent': [],
                            'heap_usage_percent': []}
        #log start time
        start_time = None
        # log end time
        finish_time = None
        # gc work thread count
        gc_work_thread_number = None
 
        each_line = reader.next()
 
        while each_line:
            if self.__is_start_line(each_line):
                token = each_line.split(' ')
                total_stop_time += float(token[5])
 
                if start_time is None:
                    start_time = self.__get_datetime(token[0])
                finish_time = token[0]
 
                gc_count += 1
 
                gc_type = token[4][1:-2]
                if gc_type == 'young':
                    gc_count_young += 1
                elif gc_type == 'mixed':
                    gc_count_mixed += 1
 
            elif each_line.find('   [Eden:') == 0:
                '''
                parse memory info
                '''
                memory_info = each_line.split(' ')
 
                eden_info = self.__parse_memory_info(memory_info[4])
 
                survivor_info = self.__parse_memory_info(memory_info[6])
 
                if survivor_size is None:
                    survivor_size = survivor_info[1]
 
                heap_info = self.__parse_memory_info(memory_info[8])
 
                max_heap_size = max(max_heap_size, heap_info[1])
                min_heap_size = min(heap_info[1], min_heap_size)
                # garbage (heap) / before gc (heap)
                memory_usage_map['heap_garbage_percent'].append(float(heap_info[0] - heap_info[2]) / heap_info[0])
                # before gc (heap) / heap size
                memory_usage_map['heap_usage_percent'].append(float(heap_info[0]) / heap_info[1])
                max_eden_size = max(max_eden_size, eden_info[1])
                min_eden_size = min(eden_info[1], min_eden_size)
                # garbage (eden+survivor) / before gc (eden+survivor)
                memory_usage_map['young_garbage_percent'].append(
                    float(eden_info[0] + survivor_info[0] - eden_info[2] - survivor_info[1]) / (
                        eden_info[0] + survivor_info[0]))
                # before gc(eden+survivor) / eden+survivor*2
                memory_usage_map['young_usage_percent'].append(
                    float(eden_info[0] + survivor_info[0]) / (eden_info[1] + survivor_info[1] * 2))
                total_eden_size += eden_info[1]
 
            elif gc_work_thread_number is None and each_line.find('      [GC Worker Start') == 0:
                gc_work_thread_number = len(each_line.strip().split('  ')) - 1
 
            each_line = reader.next()
 
        finish_time = self.__get_datetime(finish_time)
 
        reader.close()
 
        print '''G1 log Time:
        [%s] - [%s]''' % (
            start_time.strftime('%Y-%m-%d %H:%M:%S'), finish_time.strftime('%Y-%m-%d %H:%M:%S'))
 
        summary = '''Memory Info:
        Min Heap Size\t= %sM
        Max Heap Size\t= %sM
        Min Eden Size\t= %sM
        Max Eden Size\t= %sM
        Avg Eden Size\t= %sM
        Survivor Size\t= %sM''' % (
        (max_heap_size / 1024), (min_heap_size / 1024), (max_eden_size / 1024), (min_eden_size / 1023),
        (total_eden_size / gc_count / 1024), survivor_size / 1024)
 
        print summary
 
        gc_info = '''GC Info:
        GC Work Threads\t= %s
        Avg Stop Time\t= %.2fms
        GC Throughput\t= %.2f%%
        ''' % (gc_work_thread_number, (total_stop_time * 1000 / gc_count),
               total_stop_time * 100 / (finish_time.second - start_time.second))
 
        gc_info += '''GC(yong) Times\t= %s
        GC(mixed) Times\t= %s
        Total GC Times\t= %s
        ''' % (gc_count_young, gc_count_mixed, gc_count)
 
        gc_info += '''Avg Yong Generation Garbage Rate\t= %.2f%%
        Avg Heap Garbage rate\t= %.2f%%
        ''' % (sum(memory_usage_map['young_garbage_percent']) * 100 / len(memory_usage_map['young_garbage_percent']),
               sum(memory_usage_map['heap_garbage_percent']) * 100 / len(memory_usage_map['heap_garbage_percent']))
 
        gc_info += '''Avg Max Young Generation Usage Rate\t=%.2f%%
        Avg Max Heap Usage Rate\t=%.2f%%
        ''' % (sum(memory_usage_map['young_usage_percent']) * 100 / len(memory_usage_map['young_garbage_percent']),
               sum(memory_usage_map['heap_usage_percent']) * 100 / len(memory_usage_map['heap_usage_percent']))
 
        print  gc_info
 
    # get datetime from header line
    def __get_datetime(self, str):
        # time like this '2012-12-12T19:01:28.610'
        datetime_string = str
        if len(str) > 23:
            datetime_string = str[0:23]
        return datetime.datetime.strptime(datetime_string, '%Y-%m-%dT%H:%M:%S.%f')
 
    # test if the line is g1 log start line
    def __is_start_line(self, line):
        #pattern = re.compile('^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:')
        return self.__START_LINE_PATTERN.match(line) is not None
 
    # private reader for read each line
    def __reader(self, path):
        log_file = open(path, 'r')
        line = log_file.readline()
        while line:
            yield line
            line = log_file.readline()
        log_file.close()
        yield None
 
    '''
    parse memory info to a tuple in kilobyte
    eg: 1M->1M parse to (1024,1024)
        2M(2M)->0B(1M) parse to (2028,2048,0,1024)
    '''
 
    def __parse_memory_info(self, info):
        match = self.__MEMORY_INFO_PATTERN.match(info)
        if match:
            cell = match.groups()
            return int(cell[0]) * self.__unit2kb(cell[1]), int(cell[2]) * self.__unit2kb(cell[3]), int(
                cell[4]) * self.__unit2kb(cell[5]), int(cell[6]) * self.__unit2kb(cell[7])
 
        match = self.__SIMPLE_MEMORY_INFO_PATTERN.match(info)
        if match:
            cell = match.groups()
            return int(cell[0]) * self.__unit2kb(cell[1]), int(cell[2]) * self.__unit2kb(cell[3])
 
        return None
 
    # covert unit to KB
    # M = 1024K
    # G = 1024K = 1024K*1024
    def __unit2kb(self, unit):
        if unit == 'M':
            return 1024
        elif unit == 'K':
            return 1
        elif unit == "G":
            return 1048576
        else:
            return 1
 
if __name__ == '__main__':
    analyseG1Log = G1LogUtil('/Users/lichengwu/tmp/mtcms-debug.gc.log.2012-12-20')
    analyseG1Log.analyse()

输出日志:

G1 log Time:
        [2012-12-19 10:25:12] - [2012-12-20 17:22:16]
Memory Info:
        Min Heap Size  = 1024M
        Max Heap Size	= 1024M
        Min Eden Size	= 128M
        Max Eden Size	= 112M
        Avg Eden Size	= 117M
        Survivor Size	= 16M
GC Info:
        GC Work Threads	= 6
        Avg Stop Time	= 61.31ms
        GC Throughput	= 91.97%
        GC(yong) Times	= 60
        GC(mixed) Times	= 0
        Total GC Times	= 60
        Avg Yong Generation Garbage Rate	= 91.38%
        Avg Heap Garbage rate	= 39.49%
        Avg Max Young Generation Usage Rate	=92.06%
        Avg Max Heap Usage Rate	=29.38%

  几个参数解释:

  • GC Work Threads GC工作线程数
  • Avg Stop Time  平均停顿时间
  • GC Throughput  吞吐量
  • GC(yong) Times  新生代GC次数(严格来说是新生代region 下同)
  • GC(mixed) Times 混合GC次数(新生代region+老年代region)
  • Total GC Times 总gc次数
  • Avg Yong Generation Garbage Rate 新生代垃圾比例
  • Avg Heap Garbage rate 老年代垃圾比例
  • Avg Max Young Generation Usage Rate 新生代内粗平均最大利用率
  • Avg Max Heap Usage Rate  老年代内存平均利用率

稍后可能会加入一些图表和其他分析结果:

 

持续更新地址:https://gist.github.com/4353790

1
1
分享到:
评论
1 楼 he_wen 2012-12-23  
请问一下 G1算法是否在线上使用了?

相关推荐

    深入理解JVM & G1 GC

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

    jdk20-hotspot-virtual-machine-garbage-collection-tuni

    4. **垃圾收集器类型**:HotSpot提供了多种GC策略,如Serial GC、Parallel GC、Parallel Old GC、CMS(Concurrent Mark Sweep)、G1(Garbage-First)和ZGC(Zing Concurrent Low Latency Collector)。每种收集器有...

    jvm工具、参数调优&调试技巧

    2. 垃圾收集器选择:如CMS(Concurrent Mark Sweep)适合低停顿时间的应用,G1(Garbage First)则适用于大内存、多核的环境。 3. 类加载优化:-XX:+UseConcMarkSweepGC启用并发标记清除垃圾收集器,-XX:+...

    JDK19-hotspot-virtual-machine-garbage-collection-tuning-guide

    4. Garbage-First(G1)垃圾收集器:G1垃圾收集器是Java 7中引入的新型垃圾收集器,使用增量式标记-清除算法。 5. Z垃圾收集器(Z Garbage Collector):Z垃圾收集器是Java 11中引入的低延迟垃圾收集器,使用增量式...

    JDK9-JSE-HotSpot Virtual Machine Garbage Collection-53.pdf

    在实际操作中,开发者通常需要结合性能测试、内存分析工具以及JVM提供的各种监控选项,才能找出最佳的配置。理解不同垃圾收集器的工作原理和特点,以及它们对应用程序性能的影响,是进行有效调优的关键。

    自己的系统的gc参数学习

    四、GC日志分析 描述中提到的"gc.log"文件记录了垃圾收集过程的详细信息,包括收集开始时间、持续时间、暂停时间、各代内存占用情况等。通过分析这些日志,我们可以评估GC性能,优化参数配置,例如找出可能导致长...

    JVM性能调优-JVM内存整理及GC回收.pdf_java_jvm_

    3. **监控与诊断**:使用JVisualVM、JConsole等工具进行实时监控,分析GC日志,找出性能瓶颈。 4. **对象生命周期管理**:合理设计对象生命周期,避免大量短生命周期对象晋升到老年代,导致不必要的Full GC。 5. *...

    成为JavaGC专家PartII-如何监控Java垃圾回收

    3. **GC策略与调优**:Java提供了多种GC算法,如Serial、Parallel、Concurrent Mark Sweep (CMS) 和 Garbage First (G1)。每种策略都有其适用场景和优缺点。例如,G1适合大内存、低延迟的应用,而CMS则在内存较小、...

    ibm pattern modeling and analysis tool for java

    它可以分析不同类型的GC策略,包括串行GC、并行GC、CMS(Concurrent Mark Sweep)和G1(Garbage-First)等,为每个策略提供定制的分析。 在提供的文件列表中,"ga441.jar"很可能是IBM GA工具的可执行JAR文件,用于...

    GCHisto JDK7和JDK8

    在JDK7中,G1(Garbage-First)垃圾收集器开始成为一种可选的并行垃圾收集策略,其目标是提供更可预测的暂停时间。GCHisto可以分析G1收集器的活动,展示不同阶段(如年轻代收集、老年代收集等)的耗时,帮助开发者...

    jrockit 手册

    1. **内存分配与垃圾收集**:JRockit提供了多种垃圾收集器,如Parallel GC、Concurrent Mark Sweep (CMS) 和Garbage-First (G1)。选择合适的垃圾收集器可以显著改善性能。例如,对于需要低暂停时间的应用,CMS是一个...

    深入理解G垃圾收集器.docx

    日志分析可以帮助我们理解G1的行为,例如`[GC pause (young), 0.23094400 secs]`记录了一次YGC,显示了GC的暂停时间、内存变化以及各区域的占用情况。通过监控这些日志,我们可以优化垃圾收集参数,进一步提升应用...

    GC-PowerStation.rar

    1. **GC算法分析**:GC-PowerStation可能提供对多种垃圾收集算法的详细分析,如Serial、Parallel、CMS(Concurrent Mark Sweep)、G1(Garbage-First)和ZGC(Zing Garbage Collector)等。每种算法都有其适用场景和...

    jvm 调优建议文档

    - **G1垃圾收集器详解**:G1(Garbage First)是一种面向服务端应用的垃圾收集器,它将堆划分为多个区域(region),每个区域都可以充当年轻代或老年代的一部分,具有较好的可预测性,并能较好地控制GC暂停时间。...

    gcviewer-1.33

    其次,GCViewer支持多种GC算法的分析,包括串行GC、并行GC、CMS(Concurrent Mark Sweep)、G1(Garbage-First)以及ZGC(Z Garbage Collector)等。不同的GC算法有着不同的优化目标和工作模式,通过GCViewer,...

    性能工程师指南:玩转OpenJDK HotSpot垃圾收集器

    - G1 GC(Garbage First):综合考虑吞吐量和延迟,适用于大型堆。 #### 六、结论 综上所述,性能工程是一个综合性的领域,涉及到软件开发的多个方面。特别是在Java应用中,合理配置和优化JVM的垃圾收集器是提高...

    gchisto.jar

    4. **GC策略**:了解JVM采用的特定GC策略,如CMS(Concurrent Mark Sweep)、G1(Garbage-First)等,以便根据应用需求优化配置。 通过gchisto.jar,开发者可以快速定位到可能导致性能瓶颈的GC行为,进一步优化JVM...

    visualVM插件包Branch GC等

    VisualVM是一款强大的Java应用程序性能分析工具,由Oracle公司开发并维护。它提供了丰富的功能,包括内存分析、线程检查、CPU使用率监控、JVM配置信息查看以及各种JVM垃圾收集器(GC)的详细信息展示。在"visualVM...

    Jvm优化的Java -Demo

    年轻代GC通常使用ParNew或G1,而老年代则可能采用CMS(Concurrent Mark Sweep)或G1(Garbage-First)。每个算法都有其优势和适用场景,比如,G1 GC旨在提供可预测的停顿时间,适合服务端应用;而CMS则以低延迟为...

    gcparse:已退役。 Java垃圾收集日志记录的ANTLR语法

    Java提供了多种垃圾收集器,如Serial、Parallel、CMS(Concurrent Mark Sweep)、G1(Garbage-First)和ZGC(Z Garbage Collector)等,每种收集器都有其独特的日志格式。gcparse可能支持其中一种或多种垃圾收集器的...

Global site tag (gtag.js) - Google Analytics