java 在调查内存使用情况时 GC_FOR_ALLOC 是否更“严重”?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11260761/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 04:25:43  来源:igfitidea点击:

Is GC_FOR_ALLOC more "serious" when investigating memory usage?

javaandroidgarbage-collection

提问by Andrew Weir

I'm currently investigating garbage collection problems with my Android app, and I'm curious to know if GC_FOR_ALLOC is indicative of a bigger problem than other GC messages, such as GC_CONCURRENT.

我目前正在调查我的 Android 应用程序的垃圾收集问题,我很想知道 GC_FOR_ALLOC 是否表示比其他 GC 消息(例如 GC_CONCURRENT)更大的问题。

From my understanding, GC_CONCURRENT is doing what the garbage collector should do. The heap has reached a particular limit, better go clean up memory.

根据我的理解,GC_CONCURRENT 正在做垃圾收集器应该做的事情。堆已达到特定限制,最好去清理内存。

GC_FOR_ALLOC suggests to me something more serious is happening if I'm trying to create an object and there's no memory left to do it.

GC_FOR_ALLOC 向我表明,如果我试图创建一个对象并且没有剩余的内存来执行此操作,则会发生更严重的事情。

Is there a priority or "seriousness" level for the GC messages?

GC 消息是否有优先级或“严重性”级别?

回答by Martin Nordholts

In a sense, GC_FOR_ALLOCis more serious than GC_CONCURRENT, because GC_FOR_ALLOCmeans there were not enough free memory to fulfill an allocation request, so a garbage collection was necessary, whereas GC_CONCURRENTjust means that the GC felt like running, typically because the amount of free memory became lower than a certain threshold after an allocation.

从某种意义上说,GC_FOR_ALLOC比 更严重GC_CONCURRENT,因为GC_FOR_ALLOC意味着没有足够的可用内存来满足分配请求,因此垃圾收集是必要的,而GC_CONCURRENT只是意味着 GC 感觉像在运行,通常是因为可用内存量变得低于分配后的某个阈值。

A GC_FOR_ALLOCis by itself not a sign of a problem in your application however:

AGC_FOR_ALLOC本身并不是您的应用程序中存在问题的迹象:

  • Android applications start with a small heap which grows (up to a point) when applications require more and more memory, and a GC_FOR_ALLOCis done before increasing the size of the heap. In this case GC_FOR_ALLOCis perfectly normal.
  • If you allocate memory faster than the concurrent GC has time to free it up, GC_FOR_ALLOCis inevitable. And there's nothing inherently wrong with allocating memory faster than the concurrent GC can free up memory.
  • Android 应用程序从一个小堆开始,当应用程序需要越来越多的内存时,它会增长(达到一定程度),并且GC_FOR_ALLOC在增加堆的大小之前完成。在这种情况下GC_FOR_ALLOC是完全正常的。
  • 如果你分配内存的速度比并发 GC 有时间释放它的速度快,这GC_FOR_ALLOC是不可避免的。并且以比并发 GC 释放内存更快的速度分配内存并没有本质上的错误。

A more serious type of GC on Android is GC_BEFORE_OOM, which is performed when an allocation request fails even after GC_FOR_ALLOCand when the application heap has grown as big as it is allowed to be. When this happen, as a last resort, Dalvik will try to release SoftReferences as well, before doing a final attempt at allocating memory and if that fails throw an OutOfMemory exception.

Android 上一种更严重的 GC 类型是GC_BEFORE_OOM,当分配请求失败时执行,即使在GC_FOR_ALLOC应用程序堆已经增长到允许的大小之后也是如此。发生这种情况时,作为最后的手段,Dalvik 也会尝试释放 SoftReferences,然后再尝试分配内存,如果失败则抛出 OutOfMemory 异常。

If you're curious to look at the code for this logic, it is in tryMalloc()in dalvik.git/vm/alloc/Heap.cpp

如果你想看这个逻辑的代码,它tryMalloc()dalvik.git/vm/alloc/Heap.cpp

Anyway, if you don't mind, I doubt that looking at logcat output is the most efficient way to debug your garbage collection problems. I don't know what specific problem you are having, but have you looked into tools such as the Allocation Tracker in DDMS and analyzing heap dumps with the help of the hprof-convtool? (See http://android-developers.blogspot.se/2011/03/memory-analysis-for-android.htmlfor example to get started.)

无论如何,如果您不介意,我怀疑查看 logcat 输出是调试垃圾收集问题的最有效方法。我不知道您遇到了什么具体问题,但是您是否研究过 DDMS 中的 Allocation Tracker 等工具并在该hprof-conv工具的帮助下分析堆转储?(例如,请参阅http://android-developers.blogspot.se/2011/03/memory-analysis-for-android.html以开始使用。)