Ответ 1
В некотором смысле GC_FOR_ALLOC
более серьезен, чем GC_CONCURRENT
, потому что GC_FOR_ALLOC
означает, что для выполнения запроса на распределение не хватает свободной памяти, поэтому сбор мусора необходим, тогда как GC_CONCURRENT
означает, что GC чувствовал себя как работает, как правило, потому что количество свободной памяти становилось ниже определенного порога после выделения.
A GC_FOR_ALLOC
сам по себе не является признаком проблемы в вашем приложении:
- Приложения для Android начинаются с небольшой кучи, которая растет (до точки), когда приложениям требуется все больше и больше памяти, а
GC_FOR_ALLOC
выполняется до увеличения размера кучи. В этом случаеGC_FOR_ALLOC
совершенно нормально. - Если вы выделяете память быстрее, чем у параллельного GC есть время, чтобы освободить ее,
GC_FOR_ALLOC
неизбежно. И нет ничего неправильного в распределении памяти быстрее, чем параллельный GC может освободить память.
Более серьезный тип GC на Android - это GC_BEFORE_OOM
, который выполняется, когда запрос на распределение не срабатывает даже после GC_FOR_ALLOC
, и когда куча приложения выросла настолько, насколько это разрешено. Когда это произойдет, в крайнем случае, Dalvik попытается также выпустить SoftReferences, прежде чем делать окончательную попытку выделить память, и если это не сработает, исключите исключение OutOfMemory.
Если вам интересно посмотреть на код этой логики, он находится в tryMalloc()
в dalvik.git/vm/alloc/Heap.cpp
В любом случае, если вы не возражаете, я сомневаюсь, что просмотр вывода logcat является наиболее эффективным способом отладки ваших проблем с сборкой мусора. Я не знаю, какую конкретную проблему вы испытываете, но вы изучили такие инструменты, как Tracker Allocation Tracker в DDMS и анализ дампов кучи с помощью инструмента hprof-conv
? (См. http://android-developers.blogspot.se/2011/03/memory-analysis-for-android.html, например, чтобы начать.)