如果你看到 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
GC_FOR_MALLOC 表示 GC 被触发是因为堆上没有足够的内存来执行分配。可能在创建新对象时触发。
GC_EXPLICIT 表示垃圾收集器已被明确要求收集,而不是由堆中的高水位标记触发。发生在所有地方,但最有可能发生在线程被杀死或绑定通信被取消时。
还有一些其他的:
GC_CONCURRENT 当堆达到一定数量的要收集的对象时触发。
GC_EXTERNAL_ALLOC 表示虚拟机正在尝试减少用于可收集对象的内存量,为更多不可收集对象腾出空间。
更新:在更高版本的 Android 中,第一个事件的名称发生了变化。它现在称为“GC_FOR_ALLOC”。还有一个可用的新事件,虽然在现代手机中非常罕见:GC_BEFORE_OOM 表示系统运行的内存非常低,并且执行了最终 GC,以避免调用低内存杀手。
另一个解释 Dalvik 垃圾收集器消息的地方是这个视频:Google I/O 2011: Memory management for Android Apps
在演示开始大约 14 分钟时,他分解了消息格式。 (顺便说一句,该视频在调试内存泄漏方面提供了非常好的信息)
粗略地说,格式是[Reason] [Amount Freed], [Heap Statistics], [External Memory Statistics], [Pause Time]
原因
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
我还在 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;
GC_FOR_MALLOC
,而是看到了GC_FOR_ALLOC
。这是同一个事件,只是被重命名为删除 malloc() 名称引用,还是不同的事件?