Сборщик мусора в Android

Я видел много ответов на Android, которые предлагают вызвать сборщик мусора в некоторых ситуациях.

Хорошо ли запрашивать сборщик мусора в Android, прежде чем делать голодную операцию? Если нет, должен ли я называть его только, если я получаю ошибку OutOfMemory?

Есть ли другие вещи, которые я должен использовать, прежде чем прибегать к сборщику мусора?

Ответ 1

Для версий до 3.0 сотов: Да, звоните System.gc().

Я попытался создать Bitmaps, но всегда получал ошибку "VM out of memory". Но, когда я сначала назвал System.gc(), все было в порядке.

При создании растровых изображений Android часто терпит неудачу с ошибками памяти и не пытается сначала собрать мусор. Следовательно, вызовите System.gc(), и у вас достаточно памяти для создания растровых изображений.

Если вы создаете объекты, я думаю, что System.gc будет вызываться автоматически, если это необходимо, но не для создания растровых изображений. Он просто терпит неудачу.

Поэтому я рекомендую вручную вызывать System.gc() перед созданием растровых изображений.

Ответ 2

Вообще говоря, при наличии сборщика мусора никогда не бывает хорошей практики вручную вызвать GC. GC организован вокруг эвристических алгоритмов, которые лучше всего работают, когда оставляют их собственные устройства. Вызов GC вручную часто снижает производительность.

Иногда, в некоторых относительно редких ситуациях, можно обнаружить, что конкретный GC ошибается, и ручной вызов GC может затем улучшать вещи по производительности. Это связано с тем, что на самом деле невозможно реализовать "идеальный" GC, который оптимально управляет памятью во всех случаях. Такие ситуации трудно предсказать и зависеть от многих тонких деталей реализации. "Хорошая практика" - позволить GC работать сама по себе; ручным вызовом в GC является исключение, которое должно быть предусмотрено только после того, как фактическая проблема с производительностью была должным образом засвидетельствована.

Ответ 3

Недостаточно памяти в приложении Android очень часто, если мы неправильно обрабатываем растровое изображение, Решение проблемы было бы

if(imageBitmap != null) {
     imageBitmap.recycle();
     imageBitmap = null;
}
System.gc();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 3;
imageBitmap = BitmapFactory.decodeFile(URI, options);
Bitmap  scaledBitmap = Bitmap.createScaledBitmap(imageBitmap, 200, 200, true);
imageView.setImageBitmap(scaledBitmap);

В приведенном выше коде просто попробовали переработать растровое изображение, которое позволит вам освободить используемое пространство памяти, поэтому может не произойти нехватка памяти. Я пробовал, чтобы это сработало для меня.

Если вы все еще сталкиваетесь с проблемой, вы также можете добавить эту строку

BitmapFactory.Options options = new BitmapFactory.Options();
options.inTempStorage = new byte[16*1024];
options.inPurgeable = true;

для получения дополнительной информации ознакомьтесь с этой ссылкой

http://voices.yahoo.com/android-virtual-machine-vm-out-memory-error-7342266.html


ПРИМЕЧАНИЕ. Из-за кратковременной паузы, вызванной выполнением gc, не рекомендуется делать это перед каждым распределением растровых изображений.

Оптимальный дизайн:

  • Освободите все растровые изображения, которые больше не нужны, с помощью приведенного кода if / recycle / null. (Сделайте способ, чтобы помочь с этим.)

  • System.gc();

  • Выделите новые растровые изображения.

Ответ 4

Если вы получаете OutOfMemoryError, то обычно слишком поздно вызывать сборщик мусора...

Вот цитата из Android-разработчика:

В большинстве случаев сбор мусора происходит из-за тонны мелких, недолговечные объекты и некоторый мусор коллекционеры, такие как генераторный мусор коллекционеров, может оптимизировать сбор этих объектов, чтобы приложение не получает слишком часто прерывается. Android сборщик мусора, к сожалению, нет способны выполнять такую ​​оптимизацию и создание короткоживущих объектов в критические кодовые пути производительности таким образом, очень дорого для вашего приложения.

Поэтому, насколько я понимаю, нет необходимости называть gc. Лучше потратить больше усилий, чтобы избежать ненужного создания объектов (например, создание объектов внутри циклов).

Ответ 5

Мое приложение управляет множеством изображений, и оно умерло с помощью OutOfMemoryError. Это помогло мне. В Manifest.xml Добавить

<application
....
   android:largeHeap="true"> 

Ответ 6

Кажется, что System.gc() не работает на Art Android 6.0.1 Nexus 5x, поэтому я использую Runtime.getRuntime().gc();.

Ответ 7

Вообще говоря, вы не должны явно обращаться к GC с помощью System.gc(). Существует даже лекция IO (http://www.youtube.com/watch?v=_CruQY55HOk), где они объясняют, что означает, что GC делает паузу в журнале, и в котором они также заявляют, что никогда не должны звонить в System.gc(), потому что Дальвик знает лучше вас, когда это делается.

С другой стороны, как упоминалось выше, уже процесс GC в Android (как и все остальное) иногда бывает ошибочным. Это означает, что алгоритмы Dalvik GC не совпадают с JVM Hotspot или JRockit и могут иногда ошибиться в некоторых случаях. Одним из таких случаев является выделение растровых объектов. Это сложно, потому что он использует память Heap и Non Heap и потому, что один экземпляр объекта bitmap на устройстве с ограниченным объемом памяти достаточно, чтобы дать вам исключение OutOfMemory. Поэтому, называя его после того, как вам не нужно это растровое изображение, как правило, предлагают многие разработчики, и некоторые считают, что это хорошая практика.

Более эффективная практика использует .recycle() в растровом изображении, так как для этого используется этот метод, поскольку он отмечает, что собственная память растрового изображения является безопасной для удаления. Имейте в виду, что это очень зависит от версии, а это значит, что в большинстве случаев это потребуется для старых версий Android (Pre 3.0, я думаю), но не потребуется для более поздних версий. Кроме того, это не повредит, используя его на более новых версиях ether (просто не делайте этого в цикле или что-то в этом роде). Новое время работы в ART изменилось здесь, потому что они внедрили специальный раздел "Куча" для больших объектов, но я думаю, что это не будет сильно заставлять это делать с использованием эфира ART.

Также очень важно отметить System.gc(). Этот метод не является обязательством, на которое Dalvik (или JVM) обязаны отвечать. Считайте, что это больше похоже на высказывание виртуальной машине "Не могли бы вы сделать сборку мусора, если это не хлопот".

Ответ 9

Нет необходимости вызывать сборщик мусора после OutOfMemoryError.

В нем Джавадок четко заявляет:

Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector.

Итак, сборщик мусора уже пытался освободить память перед генерированием ошибки, но не увенчался успехом.

Ответ 10

Я бы сказал "нет", потому что "Документация разработчика по использованию ОЗУ" :

...
GC_EXPLICIT

Явный GC, например, когда вы вызываете gc() (которому следует избегать вызова и вместо этого доверять GC для запуска при необходимости).

...

Я выделил соответствующую часть жирным шрифтом.

Посмотрите на серию YouTube, Android Performance Patterns - она ​​покажет вам советы по управлению использованием памяти приложения (например, с помощью Android ArrayMap и SparseArray вместо HashMap s).

Ответ 11

Быстрая заметка для разработчиков Xamarin.

Если вы хотите называть System.gc() в приложениях Xamarin.Android, вы должны позвонить Java.Lang.JavaSystem.Gc()