Android GC Log

最近在研究Android内存垃圾回收的内容,遇到一些自己之前不知道的技巧和方法。现在分享一种简单的在Logcat中可以看到垃圾回收状态的方法。经常关注Logcat日志的童鞋偶尔会看到一条类似于以下形式的记录。这种记录就是系统执行垃圾回收后返回的状态信息。

Dalvik虚拟机的Log信息

在Davlik虚拟机(非ART)中,每一次垃圾回收都会返回一条类似的信息。例子如下:

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

它们大致可以分成如下几个部分:

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

各个字段的含义如下:

  • <GC_Reason> GC的原因,也就是GC类别。它包含以下几种类别:
    • GC_CONCURRENT 当堆将要被填满的时候触发的垃圾回收
    • GC_FOR_MALLOC 当应用的堆已经被填满的时候,如果应用继续申请内存就会触发此类垃圾回收。系统会杀死应用的进程并且回收所有内存。
    • GC_HPROF_DUMP_HEAP 当请求生成HPROF文件来分析内存的时候会触发此类垃圾回收
    • GC_EXPLICIT 一次指定的垃圾回收,例如主动调用System.gc()的时候。(尽量避免此类调用,垃圾回收交给系统来做就可以了)
    • GC_EXTERNAL_ALLOC 在API版本10(Android3.0)以下的时候的垃圾回收机制。3.0以上版本所有的内存都在Dalvik堆中分配。它是用来回收dalvik虚拟机以外的内存(例如Bitmap中的内存或者NIO buffer中的内存)。
  • <Amount_freed> 本次垃圾回收中释放的内存总量
  • <Heap stats> 堆中可用空间所占的百分比 和 (堆中对象的数量)/(堆的大小)
  • <External memory stats> 系统API版本10以下的系统中, Dalvik虚拟机堆外 (分配的内存) / (限制的内存量)
  • <Pause time> 垃圾回收过程中应用暂停挂起的时间。Concurrent类型的垃圾回收有两次暂停时间:一次发生在开始,另一次发生在结束。堆的内容越多,暂停的时间越长。

观察这些Log信息,如果heap stats中的数值(堆中对象数量)/(堆的大小)越来越大,那么应用中很有可能存在内存泄漏。

ART的Log信息

不像Dalvik虚拟机,ART不会把所有的GC结果都输出到Logcat中。只有那些被认为执行缓慢的GC才会被输出到Logcat中。确切的说,只有GC停顿时间超过5ms或者整个GC耗时超过100ms才会被输出到Logcat中。(注意:3.0之后垃圾回收做了优化,整个GC过程中只有一小部分时间会导致应用停顿)。主动发起的GC一定会被输出到Logcat中。ART输出的Log信息的例子如下:

I/art : Explicit concurrent mark sweep GC freed 104710(7MB) AllocSpace objects, 21(416KB) LOS objects, 33% free, 25MB/38MB, paused 1.230ms total 67.216ms

它的格式是这样的:

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_Reason> 触发垃圾回收的原因以及触发了何种类型的垃圾回收,它包含以下几类:
    • Concurrent 特点是不需要挂起应用线程。它在后台线程中运行,不会影响到内存的分配。
    • Alloc 它在应用申请内存但是堆已满的情况下触发。在这种情况下,垃圾回收在分配内存的线程中进行。(它会导致应用暂停一段时间)
    • Explicit 主动发起的垃圾回收,例如System.gc()。跟dalvik一样,建议不要主动发起垃圾回收。
    • NativeAlloc 它会在native层内存吃紧的时候发起。比如说分配Bitmap或者RenderScript内存空间不够的时候。
    • CollectorTransition 一般由堆转换引起,垃圾回收器会把free-list back空间的所有对象都复制到bump pointer空间中。目前,转换过程只在一些低内存的设备上应用所在进程从对暂停敏感切换到对暂停不敏感状态的时候发生。
    • HomogeneousSpaceCompact 它是在free-list 空间到free-list空间的复制。当app所在进程对暂停不敏感的时候发生。它可以减少内存的使用,减少内存分配的碎片化。
    • DisableMovingGc 它并不是引起内存回收的真正原因,它是垃圾回收被GetPrimitiveCritical中断时发生的。当concurrent 堆压缩正在执行的时候,因为对垃圾回收器的限制,所以非常不建议使用它。
    • HeapTrim 它不是触发垃圾回收的原因,但是在堆压缩的时候垃圾回收会被终止。
  • GC Name 垃圾回收的名称,一共有如下几类:
    • Concurrent mark sweep(CMS) 对整个堆进行垃圾回收,除了image空间。
    • Concurrent partial mark sweep 对几乎整个堆进行回收,除了image空间和zynote空间。
    • Concurrent sticky mark sweep 一次普通的垃圾回收,它只负责回收上次垃圾回收之后的分配的对象。它要比Concurrent partial mark sweep执行的次数频繁的多,因为它的执行速度快,暂停时间少。
    • Marksweep + semispace 一种非同时进行的,包含复制过程的GC。可以用来移动堆,也可以用来压缩堆(减少堆的碎片化)。
  • Objects freed 释放了对象(非大对象)的数量
  • Size freed 释放了空间(非大对象)的大小
  • Large objects freed 释放了大对象的数量
  • Large object size freed 释放了大对象的空间的大小
  • Heap stats 堆中空闲空间的百分比 和 (对象的个数)/(堆的总空间)
  • Pause times 一般情况下,垃圾回收的暂停时间跟堆中引用的数量成正比。目前,ART CMS GC 只有一次在垃圾回收结束的时候。内存转移的GC在整个过程中有一个长时间的暂停。

同样,在使用ART的情况下,如果Logcat中看到大量的GC的记录。并且Heap stats信息中的(对象数/堆的空间)的数值不断增长,没有变小的趋势。那么应用很有可能存在内存泄漏。
如果看到GC Reason对应的信息变成了 “Alloc”,那说明应用的堆几乎满了,接下来马上要内存溢出了。

参考文章:Ivestigating Your RAM Usage

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容