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

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

102 голосов
/ 25 июня 2010

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

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

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

Ответы [ 11 ]

139 голосов
/ 11 декабря 2010

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

Я пытался создать растровые изображения, но всегда получал сообщение об ошибке «ВМ недостаточно памяти». Но когда я сначала позвонил System.gc(), все было в порядке.

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

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

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

115 голосов
/ 25 июня 2010

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

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

26 голосов
/ 21 июня 2012

Недостаточно памяти в приложении для 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, это не рекомендуется сделать это до каждого выделения растрового изображения.

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

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

  2. System.gc();

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

19 голосов
/ 25 июня 2010

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

Вот цитата из Android Developer:

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

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

7 голосов
/ 18 февраля 2016

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

7 голосов
/ 27 июля 2014

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

<application
....
   android:largeHeap="true"> 
6 голосов
/ 18 июля 2014

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

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

Лучшей практикой является использование .recycle () для растрового изображения, поскольку именно для этого и создан этот метод,поскольку он отмечает собственную память растрового изображения как безопасную дляудалять.Имейте в виду, что это очень зависит от версии, то есть обычно требуется в старых версиях Android (я думаю, до версии 3.0), но не требуется в более поздних.Также это не повредит, если использовать его в более новых версиях эфира (только не делайте это в цикле или что-то в этом роде).Новая среда выполнения ART сильно изменилась, потому что она ввела специальный «раздел» Heap для больших объектов, но я думаю, что это не помешает сделать это с помощью эфира ART.

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

3 голосов
/ 19 февраля 2013

Лучший способ избежать OOM при создании растрового изображения,

http://developer.android.com/training/displaying-bitmaps/index.html

2 голосов
/ 12 октября 2017

Краткое примечание для разработчиков Xamarin .

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

2 голосов
/ 08 марта 2016

Я бы сказал, что нет, потому что Разработчик документирует использование ОЗУ Состояние:

...
GC_EXPLICIT

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

...

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

Взгляните на серию YouTube, Образцы производительности Android - в ней вы найдете советы по управлению использованием памяти вашего приложения (например, использование ArrayMap s и SparseArray s в Android вместо * 1027). * s).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...