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> 本次垃圾回收中释放的内存总量
- 堆中可用空间所占的百分比 和 (堆中对象的数量)/(堆的大小)
- 系统API版本10以下的系统中, Dalvik虚拟机堆外 (分配的内存) / (限制的内存量)
- 垃圾回收过程中应用暂停挂起的时间。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
Android GC Log的更多相关文章
- android 底层log分析 内存及backtrace tombstone/crash
Build fingerprint: 'XXXXXXXXX'pid: 1658, tid: 13086 >>> system_server <<<signal 1 ...
- Android GC 那点事
版权声明:本文由陈昱全原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/170 来源:腾云阁 https://www.qclo ...
- Android GC 原理探究
导语 想写一篇关于 android GC 的想法来源于追查一个魅族手机图片滑动卡顿问题,由于不断的 GC 导致的丢帧卡顿的问题让我们想了很多方案去解决,所以就打算详细的看看内存分配和 GC 的原理,为 ...
- 实现在Android 下log的使用总结
一:在源码开发模式下 1:包含头文件: #include <cutils/log.h> 2:定义宏LOG_TAG #define LOG_TAG "MY LOG TAG&qu ...
- Android 之 log
android.util.Log常用方法: Log.v() VERBOSE 任何消息都会输出 Log.d() DEBUG 仅输出debug调试的意思,但他会输出上层的信息,过滤起来可以通过DD ...
- [转]Android输出Log到文件
前言:开发中遇到mx4这款机型Eclipse联调不上,logcat看不了,需要输出生成文件查看调试信息.网上搜了下,功能很完善了.startService和过滤输出信息需要自己添加设置,另外注意添加权 ...
- -Xloggc:log/gc.log 指定GC log的位置
-Xloggc:log/gc.log指定GC log的位置,以文件输出帮助开发人员分析问题
- Android 下log的使用总结
Android 下log的使用总结 一:在源码开发模式下 1:包含头文件: #include <cutils/log.h> 2:定义宏LOG_TAG #define LOG_TAG &qu ...
- android.util.Log说明和android 像素说明
1. android.util.Log常用的方法有以下5个:Log.v() Log.d() Log.i() Log.w() 以及 Log.e() .根据首字母对应VERBOSE,DEBUG,INFO, ...
随机推荐
- 2015最全iOS开发自学视频资料(基础+实战)
最全的iOS自学视频,包括c,objective-c,UI等等,没有你找不到的,只有你学不会的,只要你想学,这里都有你所需要的. 推荐教程点这里:http://www.mobiletrain.org/ ...
- linux iptables扩展,脚本防火墙
netfileter:防火墙内核态ip tables:防火墙用户态(管理防火墙规则) iptables的表和链表包括不同的链,链包括大量的规则4个表: raw,mangle,nat,filter5种链 ...
- 嵌入式Linux引导过程之1.3——Xloader的sys_init
上一篇文章对XLOADER_ENTRY进行了分析,看到其中调用的第一个标号就是sys_init,本文就对这个标号对应的代码段进行粗略的分析,这里我也还有好多没有搞明白的,就先留着,日后慢慢明白,先把自 ...
- MinGW下简单编译FFmpeg
2009.03.21补充:ffmpeg-0.5正式发布,地址为:[url]http://www.ffmpeg.org/releases/ffmpeg-0.5.tar.bz2[/url].修改了第7步, ...
- ASP.NET性能调试
该文转自mx5721的博客:http://blog.csdn.net/mx5721/article/details/9138135 设计考虑 性能和安全的考虑 应用程序逻辑划分的考虑:逻辑分层,然后使 ...
- h264多slice
1, h264编码以macroblock为最小单位(简称MB),多个连续的MB组成一个slice,每个slice编码输出一个NALU 2, 划分slice的方式可以按照固定个数MB的方式: 也可以以对 ...
- Android App性能评测分析-流畅度篇
1.前言 在手机App竞争越来越激烈的今天,Android App的各项性能特别是流畅度不如IOS,安卓基于java虚拟机运行,触控响应的延迟和卡顿比IOS系统严重得多.一些下拉上滑.双指缩放快速打字 ...
- 宿主机无法访问linux虚机中的网站
问题现象: Nginx服务已启动 80端口被nginx监听 宿主和linux虚机可相互ping通 Linux虚机可用curl访问网站 宿主无法用浏览器访问网站 排查: 1. 查看nginx的acce ...
- sspanelv3魔改版邮件设置指南及常用配置
要进行SSpanel v3魔改版邮件设置,需要在设置文件(位于config/.config.php下)中修改两处内容: 1.设置发送邮件的方式 $System_Config['enable_email ...
- LCA倍增算法
LCA 算法是一个技巧性很强的算法. 十分感谢月老提供的模板. 这里我实现LCA是通过倍增,其实就是二进制优化. 任何一个数都可以有2的阶数实现 例如16可以由1 2 4 8组合得到 5可以由1 2 ...