Очистка программы при выходе и работа с GC - PullRequest
3 голосов
/ 08 января 2011

Я пишу программу, которая включает в себя тонну изображений, более 100 на плотность экрана. К счастью, они не очень большие с точки зрения пространства. Я использую примерно 11 в любой момент времени. Я также использую функцию Bitmap.createScaledBitmap на каждом изображении, которое, кажется, занимает много памяти.

Пока что при отладке этого приложения я, кажется, могу использовать его бесконечно, не сталкиваясь с проблемой памяти, которая, я надеюсь, означает, что я не теряю память.

Однако я заметил одну вещь: если я «выйду» из моего приложения с помощью кнопки «назад» (я ничего не запускаю в фоновом режиме), а вскоре после этого перезапущу приложение, я иногда получаю ошибки памяти при звонке на Bitmap.createScaledBitmap

01-07 19:01:24.935: ERROR/AndroidRuntime(27419): java.lang.OutOfMemoryError: bitmap size exceeds VM budget

Итак, в основном мой вопрос: что я здесь не так делаю? Нужно ли убирать мой собственный мусор, как в onDestroy, когда пользователь нажимает кнопку «Назад»? Я бы подумал, что GC автоматически позаботится об этом, когда будет нажата кнопка «Назад» и активность будет уничтожена. Это заставляет меня поверить, что я делаю что-то еще не так, как утечка памяти. Но потом я возвращаюсь к тому факту, что мое приложение может интенсивно использовать память в течение 20 минут, а затем убить себя через 5 секунд после перезапуска, что меня и сбивает с толку.

Спасибо всем.

Редактировать: я реализовал пару быстрых и грязных исправлений.

Сначала я попробовал это, и было сложнее заставить приложение принудительно закрыться.

@Override
public void onBackPressed() {
    finish();
}

Затем я попробовал это в сочетании с onBackPressed и больше не мог дублировать мою проблему. Обратите внимание, что вызов метода - это просто цикл, который в основном выполняет allImages = null;

protected void onStop () {
    super.onStop();
    mComponent.releaseImages();
}

В этот момент кажется, что после вызова finish () в действии все еще остаются объекты в памяти. Довольно странно.

Ответы [ 3 ]

3 голосов
/ 08 января 2011

Возможно, вы неправильно поняли срок службы вашего приложения для Android. Нажатие кнопки «назад» не убивает вашу Java-программу. Так что запуск вашего приложения снова запускает новое приложение.

См. http://developer.android.com/guide/topics/fundamentals.html#actlife

Если вы, например, создаете изображения в onStart (), но не удаляете их в onStop (), у вас все еще есть ссылки на ваши изображения. Каждый раз будет добавлять больше памяти.

2 голосов
/ 08 января 2011

1: Когда ваше приложение возобновляется с помощью onResume(), ваши предыдущие Bitmap объекты загружаются еще раз. Вам необходимо убедиться, что вы не распределите все Bitmap объекты еще раз.

2: Очень часто утечки памяти вызывают эти ошибки. Объекты Bitmap все еще имеют ссылки на свое начальное состояние, когда ваше приложение возобновляется. Вы можете использовать определенный шаблон для предотвращения перераспределения тех же Bitmap объектов. Этот шаблон называется Пулы памяти , и он предотвращает фрагментацию вашей памяти.

Думайте о фрагментации вот так: Вы пытаетесь припарковать машину. Глупый человек припарковался слишком много направо, а другой тупой человек припарковался слишком много налево. Этот слот фрагментирован. Первоначально у вас должно быть достаточно места для парковки вашего автомобиля прямо в этом месте, но сама парковка теперь фрагментирована. Там нет пустого места для вашего автомобиля - на парковке заканчивается память .

Чтобы предотвратить этот сценарий, вы можете использовать шаблон Memory Pools .

Используя этот шаблон, вы можете:

  • Установите максимум Bitmap объекты, которые вы будете использовать во время время жизни приложения.
  • Запросите пустой слот при возобновлении работы приложения, а затем повторно инициализируйте ваш Bitmap объекты вместо перераспределения их.

Используя этот шаблон, вы должны убедиться:

  • что у вас достаточно места для Bitmap объектов в указанном пуле.

Однако , решение второй части вообще не нужно (эй, это хороший инструмент).

Краткое решение : Нельзя создать такое же количество Bitmap объектов, когда приложение возобновляется, когда у вас все еще есть старые ссылки Bitmap в памяти. Проверьте, загружены ли уже ваши Bitmap объекты, когда ваше приложение возобновляется, и если вы этого не сделаете, создайте их.

0 голосов
/ 17 января 2011

Эта проблема была связана с ошибкой с Android. Обратитесь к следующим ссылкам для получения информации о проблеме и некоторых обходных путях.

OutofMemoryError: размер растрового изображения превышает бюджет виртуальной машины (Android)

http://code.google.com/p/android/issues/detail?id=8488

http://mobi -solutions.blogspot.com / 2010/08 / как к, если вы-хотите-на-создать-and.html

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