У меня есть приложение, работающее с OOM с большим свободным свободным кучевым пространством, которое доступно и доступно для продажи на складе Galaxy S3. Приложение отлично работает на других устройствах.
Зная, что в традиционной Java это может быть вызвано наличием OOM в пространстве постоянного поколения, я попытался изучить, как Dalvik справляется с этим, но не смог найти ничего определенного. Androids SDK, кажется, отсутствует как MemoryUsage, так и ManagementFactory, поэтому я не могу получить их так, как вы бы в Java.
Я пытаюсь выяснить, имеет ли Android пространство для постоянного поколения, могу ли я проверить его содержимое, как я могу получить размер и бесплатно, делает ли Dalvik то, что входит в это пространство, отличное от JVM и т.д.
Также открыта для других идей, если это пространство не существует или маловероятно.
Немного информации о приложении. На S3, работающем с OOM, работает 4.1.2. Приложение использует примерно 12-25 МБ кучи, при этом максимальный размер кучи составляет около 45 МБ. Он имеет много локальных изображений ресурсов и ленивых нагрузок намного позже. Я.recylce() в растровых изображениях. Приложение падает каждый раз в одно и то же место. Я неплохо посмотрел на код вокруг пятна, который падает, и я не вижу ничего необычного. Другие устройства отлично работают с этим кодом.
Мне кажется, что вы испытываете проблему фрагментации кучи.
Вы отказываетесь от размещения 1,2 МБ в куче, у которой много свободного места. Система, вероятно, не может найти непрерывный пустой кусок размером 1,2 МБ, так как ваша куча полностью фрагментирована, и она не может увеличить вашу кучу дальше.
Теоретически, вы не должны беспокоиться о проблемах фрагментации, и автоматический GC обрабатывает его для вас.
Практически, я уже не раз видел, что предоставление GC системы помощи иногда достигает великолепных результатов.
Вот несколько идей для решения проблем фрагментации:
Запустите System.gc()
вручную в стратегически расположенных местах. Популярные места находятся во время уничтожения крупных объектов, таких как деятельность onDestroy. Другое место - перед большими выделениями, такими как Bitmaps. Перед расшифровкой любого большого растрового изображения добавьте ручной GC. Если вы хотите уменьшить количество GC позже, добавьте ручной тест для проблемных условий памяти, запросив различные функции размера кучи.
Содействуйте свободным ресурсам системы GC быстрее. Это предотвратит фрагментацию вашей кучи в первую очередь. О том, как это сделать, много материала в сети. Некоторые из головы:
StringBuilder
вместо обычных String
sВы можете измерить, насколько вы успешны, убедившись, что ваша куча не растет до огромных размеров, когда вы используете только небольшую ее часть.
Другая идея состоит в том, чтобы попытаться уменьшить распределение 1,2 МБ. Используя меньшие изображения или перемасштабируя их во время декодирования.