我目前正在调查我的 Android 应用程序的垃圾收集问题,我很想知道 GC_FOR_ALLOC 是否表明比其他 GC 消息(例如 GC_CONCURRENT)更大的问题。
据我了解,GC_CONCURRENT 正在做垃圾收集器应该做的事情。堆已经达到一定的限制,最好去清理内存。
GC_FOR_ALLOC 向我表明,如果我试图创建一个对象并且没有剩余内存可以做,那么会发生更严重的事情。
GC 消息是否有优先级或“严重性”级别?
我目前正在调查我的 Android 应用程序的垃圾收集问题,我很想知道 GC_FOR_ALLOC 是否表明比其他 GC 消息(例如 GC_CONCURRENT)更大的问题。
据我了解,GC_CONCURRENT 正在做垃圾收集器应该做的事情。堆已经达到一定的限制,最好去清理内存。
GC_FOR_ALLOC 向我表明,如果我试图创建一个对象并且没有剩余内存可以做,那么会发生更严重的事情。
GC 消息是否有优先级或“严重性”级别?
从某种意义上说,GC_FOR_ALLOC
比 更严重GC_CONCURRENT
,因为GC_FOR_ALLOC
意味着没有足够的空闲内存来满足分配请求,因此需要进行垃圾收集,而GC_CONCURRENT
只是意味着 GC 感觉像是在运行,通常是因为空闲内存量变得低于分配后的某个阈值。
但是, AGC_FOR_ALLOC
本身并不是您的应用程序出现问题的迹象:
GC_FOR_ALLOC
在增加堆大小之前完成。在这种情况下GC_FOR_ALLOC
是完全正常的。GC_FOR_ALLOC
是不可避免的。分配内存的速度比并发 GC 释放内存的速度快并没有本质上的错误。Android 上更严重的 GC 类型是GC_BEFORE_OOM
,当分配请求失败时执行,即使在GC_FOR_ALLOC
应用程序堆增长到允许的大小之后。当这种情况发生时,作为最后的手段,Dalvik 也会尝试释放 SoftReferences,然后再进行最后一次分配内存的尝试,如果失败则抛出 OutOfMemory 异常。
如果你想看看这个逻辑的代码,它tryMalloc()
在dalvik.git/vm/alloc/Heap.cpp
无论如何,如果您不介意,我怀疑查看 logcat 输出是调试垃圾收集问题的最有效方法。我不知道您遇到了什么具体问题,但是您是否研究过诸如 DDMS 中的分配跟踪器之类的工具并在该hprof-conv
工具的帮助下分析堆转储?(例如,请参阅http://android-developers.blogspot.se/2011/03/memory-analysis-for-android.html以开始使用。)