GC日志分为两种情况,一种是在Dalvik虚拟机下的GC日志,一种是ART虚拟机下的GC日志。
Dalvik
Dalvik虚拟机下的GC格式如下:
D/dalvikvm: <GC_Reason> <Amount_freed>, <Heap_stats>, <External_memory_stats>, <Pause_time>
尖括号中的依次为:
- 垃圾回收原因;
- 此次GC释放的内存量;
- 堆统计数据:堆的可用空间百分比与(活动对象数量)/(堆总大小);
- 外部内存统计数据:API10及以下等级的外部分配内存(已分配内存量)/发生回收的限值);
- 暂停时间:堆越大,暂停时间越长。并发暂停时间显示了两个暂停:一个出现在回收开始时,另一个出现在回收快要完成时。
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)>
其中依次表示为:
- 垃圾回收原因
- 垃圾回收名称
- 释放的对象:此次GC从非大型对象空间回收的对象数量;
- 释放的大小:此次GC从非大型对象空间回收的字节数量;
- 释放的大型对象:此次GC收从大型对象空间回收的对象数量;
- 释放的大型对象大小:此次GC从大型对象空间回收的字节数量;
- 堆统计数据:空闲百分比与(活动对象数量)/(堆总大小)
- 暂停时间:常情况下,暂停时间与垃圾回收运行时修改的对象引用数量成正比。当前,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
非并发、复制垃圾回收,用于堆转换以及齐性空间压缩(对堆进行碎片整理)
网友评论