Android GC日志该如何查看

作者: 姜康 | 来源:发表于2018-04-07 15:30 被阅读664次

    GC日志分为两种情况,一种是在Dalvik虚拟机下的GC日志,一种是ART虚拟机下的GC日志。

    Dalvik

    Dalvik虚拟机下的GC格式如下:

    D/dalvikvm: <GC_Reason> <Amount_freed>, <Heap_stats>, <External_memory_stats>, <Pause_time>
    

    尖括号中的依次为:

    1. 垃圾回收原因;
    2. 此次GC释放的内存量;
    3. 堆统计数据:堆的可用空间百分比与(活动对象数量)/(堆总大小);
    4. 外部内存统计数据:API10及以下等级的外部分配内存(已分配内存量)/发生回收的限值);
    5. 暂停时间:堆越大,暂停时间越长。并发暂停时间显示了两个暂停:一个出现在回收开始时,另一个出现在回收快要完成时。

    Dalvik GC原因有以下这些

    • GC_CONCURRENT
      堆开始占用内存时可以释放内存的并发垃圾回收

    • GC_FOR_MALLOC
      堆已满而系统不得不停止应用并回收内存时,应用尝试分配内存而引起的垃圾回收

    • GC_EXPLICIT
      显式垃圾回收,例如当调用 gc()时(应避免调用,而应信任垃圾回收会根据需要运行)

    • GC_HPROF_DUMP_HEAP
      当请求创建 HPROF 文件来分析堆时出现的垃圾回收

    举个例子:

    D/dalvikvm( 9050): GC_CONCURRENT freed 2049K, 65% free 3571K/9991K, external 4703K/5261K, paused 2ms+2ms
    

    在 Dalvik(而不是 ART)中,每次垃圾回收都会将以下信息打印到 logcat 中

    在这些日志消息积聚时,要注意堆统计数据的增大(上面例子中的 3571K/9991K 值)。如果此值继续增大(或可用空间持续减小),可能会出现内存泄漏。

    ART

    与Dalvik虚拟机不同的是,ART虚拟机并不会为没有明确请求的GC记录消息。那么什么时候记录呢?

    只有在认为垃圾回收速度较慢时才会打印垃圾回收日志(仅在垃圾回收暂停时间超过 5ms 或垃圾回收持续时间超过 100ms 时),如果应用未处于可察觉的暂停进程状态,那么其垃圾回收不会被视为较慢。

    始终会记录显式垃圾回收

    ART的 GC日志格式:

    I/art: <GC_Reason> <GC_Name> <Objects_freed>(<Size_freed>) AllocSpace Objects, <Large_objects_freed>(<Large_object_size_freed>) <Heap_stats> LOS objects, <Pause_time(s)>
    

    其中依次表示为:

    1. 垃圾回收原因
    2. 垃圾回收名称
    3. 释放的对象:此次GC从非大型对象空间回收的对象数量;
    4. 释放的大小:此次GC从非大型对象空间回收的字节数量;
    5. 释放的大型对象:此次GC收从大型对象空间回收的对象数量;
    6. 释放的大型对象大小:此次GC从大型对象空间回收的字节数量;
    7. 堆统计数据:空闲百分比与(活动对象数量)/(堆总大小)
    8. 暂停时间:常情况下,暂停时间与垃圾回收运行时修改的对象引用数量成正比。当前,ART CMS(Concurrent mark sweep) 垃圾回收仅在垃圾回收即将完成时暂停一次。移动的垃圾回收暂停时间较长,会在大部分垃圾回收期间持续出现。

    其中GC的原因以及名称都有多种:

    ART GC 原因有以下这些:

    • Concurrent
      不会暂停应用线程的并发垃圾回收;
      此垃圾回收在后台线程中运行,而且不会阻止分配

    • Alloc
      应用在堆已满时尝试分配内存引起的垃圾回收;
      在这种情况下,分配线程中发生了垃圾回收;

    • Explicit
      由应用明确请求的垃圾回收,例如,通过调用 gc()
      如果显式垃圾回收导致其他线程被抢占,那么它们也可能会导致卡顿(应用中出现间断、抖动或暂停),不建议手动调用gc。

    • NativeAlloc
      原生分配(如位图或 RenderScript 分配对象)导致出现原生内存压力,进而引起的回收。

    • CollectorTransition
      由堆转换引起的回收;此回收由运行时切换垃圾回收引起;
      当前,回收器转换仅在以下情况下出现:在 RAM 较小的设备上,应用将进程状态从可察觉的暂停状态变更为可察觉的非暂停状态(反之亦然)

    • HomogeneousSpaceCompact
      齐性空间压缩是空闲列表空间到空闲列表空间压缩,通常在应用进入到可察觉的暂停进程状态时发生。这样做的主要原因是减少 RAM 使用量并对堆进行碎片整理

    • HeapTrim
      这不是垃圾回收原因,但请注意,堆修剪完成之前回收会一直受到阻止

    ART GC 名称有以下这些:

    • Concurrent mark sweep (CMS)
      整个堆回收器,会释放和回收映像空间以外的所有其他空间

    • Concurrent partial mark sweep
      几乎整个堆回收器,会回收除了映像空间和 zygote 空间以外的所有其他空间

    • Concurrent sticky mark sweep
      生成回收器,只能释放自上次垃圾回收以来分配的对象。此垃圾回收比完整或部分标记清除运行得更频繁,因为它更快速且暂停时间更短

    • Marksweep + semispace
      非并发、复制垃圾回收,用于堆转换以及齐性空间压缩(对堆进行碎片整理)

    相关文章

      网友评论

        本文标题:Android GC日志该如何查看

        本文链接:https://www.haomeiwen.com/subject/uyryhftx.html