Android и запущенная OOM с оставшимся свободным пространством кучи

1

У меня есть приложение, работающее с OOM с большим свободным свободным кучевым пространством, которое доступно и доступно для продажи на складе Galaxy S3. Приложение отлично работает на других устройствах.

Зная, что в традиционной Java это может быть вызвано наличием OOM в пространстве постоянного поколения, я попытался изучить, как Dalvik справляется с этим, но не смог найти ничего определенного. Androids SDK, кажется, отсутствует как MemoryUsage, так и ManagementFactory, поэтому я не могу получить их так, как вы бы в Java.

Я пытаюсь выяснить, имеет ли Android пространство для постоянного поколения, могу ли я проверить его содержимое, как я могу получить размер и бесплатно, делает ли Dalvik то, что входит в это пространство, отличное от JVM и т.д.

Также открыта для других идей, если это пространство не существует или маловероятно.

Немного информации о приложении. На S3, работающем с OOM, работает 4.1.2. Приложение использует примерно 12-25 МБ кучи, при этом максимальный размер кучи составляет около 45 МБ. Он имеет много локальных изображений ресурсов и ленивых нагрузок намного позже. Я.recylce() в растровых изображениях. Приложение падает каждый раз в одно и то же место. Я неплохо посмотрел на код вокруг пятна, который падает, и я не вижу ничего необычного. Другие устройства отлично работают с этим кодом.

  • 0
    Опубликовать сообщения об ошибках от OOM
  • 0
    @David 07-01 14: 09: 16.936: D / dalvikvm (22514): GC_FOR_ALLOC освобожден 1432K, 48% свободен 34247K / 64711K, приостановлено 44 мс, всего 46 мс 07-01 14: 09: 16.996: D / dalvikvm (22514): GC_BEFORE_OOM освободил 31 КБ, 48% освободил 34216 КБ / 64711 КБ, приостановил 52 мс, всего 52 мс 07-01 14: 09: 16.996: E / dalvikvm-heap (22514): Недостаточно памяти на 1222696-байтовом выделении.
Показать ещё 3 комментария
Теги:
memory-management

1 ответ

0

Мне кажется, что вы испытываете проблему фрагментации кучи.

Вы отказываетесь от размещения 1,2 МБ в куче, у которой много свободного места. Система, вероятно, не может найти непрерывный пустой кусок размером 1,2 МБ, так как ваша куча полностью фрагментирована, и она не может увеличить вашу кучу дальше.

Теоретически, вы не должны беспокоиться о проблемах фрагментации, и автоматический GC обрабатывает его для вас.

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

Вот несколько идей для решения проблем фрагментации:

  1. Запустите System.gc() вручную в стратегически расположенных местах. Популярные места находятся во время уничтожения крупных объектов, таких как деятельность onDestroy. Другое место - перед большими выделениями, такими как Bitmaps. Перед расшифровкой любого большого растрового изображения добавьте ручной GC. Если вы хотите уменьшить количество GC позже, добавьте ручной тест для проблемных условий памяти, запросив различные функции размера кучи.

  2. Содействуйте свободным ресурсам системы GC быстрее. Это предотвратит фрагментацию вашей кучи в первую очередь. О том, как это сделать, много материала в сети. Некоторые из головы:

    • Если у вас есть частые небольшие выделения, попробуйте принять схему повторного использования памяти, например, создать пул объектов и повторно использовать объекты в пуле вместо выделения новых. Эта оптимизация часто наблюдается в адаптерах Android (например, повторное использование просмотров в списках просмотров)
    • Вручную установите переменные в значение null, когда они вам не понадобятся, чтобы явно отключить их от ссылочного графика и пометить их для удобства GC (то же самое касается явной очистки коллекций данных)
    • Избегайте неизменяемых классов, когда у вас много операций, например, конкатенация строк, используйте StringBuilder вместо обычных String s
    • Избегайте финализаторов полностью
    • Избегайте круговых ссылок или, по крайней мере, меняйте один из них на слабую ссылку
    • Используйте слабые ссылки в общем, где они нужны

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

Другая идея состоит в том, чтобы попытаться уменьшить распределение 1,2 МБ. Используя меньшие изображения или перемасштабируя их во время декодирования.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню