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日志该如何查看

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

  • 通过 gc.log 调优 JVM

    一、GC 日志查看 GC 日志默认是关闭的,需要查看 GC 日志首先需要开启 GC 日志。 常用 GC 日志的配置...

  • GC日志查看和分析

    GC日志查看和分析 GC日志查看 可以通过在java命令种加入参数来指定对应的gc类型,打印gc日志信息并输出至文...

  • Java GC日志分析

    1. 查看GC日志准备 2. 年轻代GC日志 3. CMS GC日志 4. CMS GC 7阶段解析 1.初始标记...

  • GC

    查看GC日志时需要用到的虚拟机参数: -XX:+PrintGC 输出GC日志-XX:+PrintGCDetail...

  • 查看GC日志

    -XX:+PrintGC 输出GC日志-XX:+PrintGCDetails 输出GC的详细日志-XX:+Prin...

  • 查看gc日志

    在idea配置参数,即可看到GC日志

  • Full GC (Metadata GC Threshold)

    问题描述 启动tomcat,查看gc日志,发现启动之时连续出现了3次Full GC,具体日志如下: 原因描述 使用...

  • idea 项目启动慢优化

    在 VM options 中加入jvm参数,重启 查看日志中的GC 次数,和GC原因,不断调整,最终full GC...

  • jvm gc日志查看

    启动参数: -XX:+PrintGC 输出GC日志-XX:+PrintGCDetails 输出GC的详细日志-XX...

网友评论

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

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