在Android Logcat中,GC_FOR_MALLOC、GC_EXPLICIT和其他GC_*代表什么意思?

64

如果您查看Android日志,您可能会看到很多这些内容。

了解它们的含义可以帮助我们更好地进行内存分配。

例如:

 28470               dalvikvm  D  GC_FOR_MALLOC freed 665 objects / 239992 bytes in 71ms
 28470               dalvikvm  D  GC_FOR_MALLOC freed 673 objects / 240288 bytes in 87ms
 21940               dalvikvm  D  GC_EXPLICIT freed 4802 objects / 185320 bytes in 78ms
 28470               dalvikvm  D  GC_FOR_MALLOC freed 666 objects / 240536 bytes in 63ms
3个回答

122

GC_FOR_MALLOC 表示由于堆内存不足而触发了垃圾回收。当创建新对象时可能会触发。

GC_EXPLICIT 表示垃圾回收器已经被明确要求进行回收,而非由堆中高水位标记触发。通常在停止线程或解除 binder 通信时发生。

还有一些其他的:

GC_CONCURRENT 当堆达到一定数量的对象需要清理时触发。

GC_EXTERNAL_ALLOC 表示虚拟机正在尝试减少可回收对象使用的内存量,以腾出更多的不可回收内存。

更新:在 Android 的后续版本中,“GC_FOR_MALLOC”事件已更名为“GC_FOR_ALLOC”。此外,还有一个新事件可用,但在现代手机上非常罕见:GC_BEFORE_OOM 表示系统内存非常低,并且进行最后一次 GC,以避免调用低内存杀手。


1
谢谢!只是想知道你从哪里获取这些信息的? - Randy Sugianto 'Yuku'
10
经验。我一直在 Android 平台源代码上做大量的工作,指导公司构建自己的 Android 设备,并培训了将近一千人进行 Android 软件开发(包括设备和应用程序)。 - Robert
1
我的应用中有一个ListView,日志中经常出现GC_CONCURRENT和一些GC_FOR_ALLOC。这个会有什么问题吗? - Sudarshan Bhat
1
Enigma,你应该检查一下绘制列表项的代码。日志信息表明,你可能每次绘制列表项时都在分配和释放内存。阅读Mark Murphy撰写的有关列表的文章系列。http://www.androidguys.com/2008/07/14/fancy-listviews-part-one/ - Robert
在我的日志中,我没有看到 GC_FOR_MALLOC,但是看到了 GC_FOR_ALLOC。这是同一个事件,只是更名以去掉 malloc() 的名称引用,还是不同的事件? - mxk
马蒂亚斯,这是同一个事件。 - Robert

36
另一个解释Dalvik垃圾收集器消息的地方在这个视频中:Google I/O 2011: Memory management for Android Apps。在演示的大约14分钟处,他详细介绍了消息格式。 (顺便说一句,该视频提供了关于调试内存泄漏的非常好的信息)
粗略地说,格式是[原因] [释放的数量],[堆统计信息],[外部内存统计信息],[暂停时间]

原因

Robert/yuku已经给出了这些含义的信息。

释放的数量

例如 freed 2125K

不言自明

堆统计信息

例如47% free 6214K/11719K

这些数字反映了GC运行后的情况。 "47% free"和6214K反映了当前堆使用情况。 11719K表示总堆大小。 据我所知,堆可以增长/缩小,因此如果达到此限制,您不一定会遇到OutOfMemoryError。

外部内存统计信息

例如external 7142K/8400K

注意:这可能仅存在于Android的Honeycomb版本之前(3.0之前)。

Honeycomb之前,位图是分配到VM之外的(例如,Bitmap.createBitmap()在本地堆上只分配几十个字节,而在外部分配位图)。 其他外部分配的示例是用于java.nio.ByteBuffers。

暂停时间

如果它是并发GC事件,则会列出两个时间。 一个是GC之前的暂停,一个是GC大部分完成时的暂停。例如paused 3ms+5ms

对于非并发GC事件,只有一个暂停时间,通常要大得多。例如paused 87ms


2
只是想确认一下,在HoneyComb及以上版本中,外部堆已经不存在了(https://groups.google.com/d/msg/android-platform/dp6GsUiBynQ/j8B3HksRmC8J)。它们现在分配在DVM堆上。 - Tony Chan

27

我也在Android源代码中找到了这段代码,dalvik/vm/alloc/Heap.h。希望对你有所帮助。

typedef enum {
    /* Not enough space for an "ordinary" Object to be allocated. */
    GC_FOR_MALLOC,
    /* Automatic GC triggered by exceeding a heap occupancy threshold. */
    GC_CONCURRENT,
    /* Explicit GC via Runtime.gc(), VMRuntime.gc(), or SIGUSR1. */
    GC_EXPLICIT,
    /* GC to try to reduce heap footprint to allow more non-GC'ed memory. */
    GC_EXTERNAL_ALLOC,
    /* GC to dump heap contents to a file, only used under WITH_HPROF */
    GC_HPROF_DUMP_HEAP
} GcReason;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接