Поиск и устранение причины большого размера кучи

Я пытаюсь понять, почему мое приложение использует так много памяти. Я часто вижу, что он использует от 15 до 18 МБ, что значительно больше, чем я ожидал. Я посмотрел на размер кучи через DDMS и увидел это:

введите здесь описание изображения

Это выглядело немного подозрительно, потому что мое приложение вообще не работает с большими изображениями. На самом деле общая сумма рисунков в моем приложении составляет около 250 КБ. Поэтому я создал дамп кучи и использовал MAT, чтобы определить, куда уходит вся эта память. массивы byte[] были самым большим потребителем, поэтому я углубился и заметил следующее:

введите здесь описание изображения

Я совершенно не понимаю, почему sPreloadedDrawables отвечает за такой большой размер сохраненной кучи. Я также понятия не имею, как определить основную причину или как ее «исправить».

Куда мне идти отсюда? Мое приложение работает в основном в фоновом режиме через службы, которые вообще не имеют дело с данными изображения. У меня есть действия, которые пользователь может использовать, но опять же, они используют небольшие чертежи, которые не объясняют такой большой размер кучи. Я также проверил наличие каких-либо неприятных случаев утечки активности и т. д., но ничего не обнаружил.

РЕДАКТИРОВАТЬ: я заметил, что размер кучи значительно меньше при запуске в эмуляторе. Это довольно запутанно. :/


person Glitch    schedule 11.03.2012    source источник
comment
Какая версия Android у вас на телефоне? Я заметил, что ICS предварительно загружает изображения, я думаю, чтобы попытаться получить более плавный пользовательский интерфейс и воспользоваться увеличенным лимитом памяти виртуальной машины. Итак, если ваш телефон на ICS, а ваш эмулятор на 2.X, это объясняет разницу. Я лично не тестировал эмулятор, работающий под управлением 4.X, чтобы проверить, присутствует ли также завышенная память (думаю, что мне нужно сделать что-то позже). Это определенно есть на моем телефоне с 4.0.3.   -  person sciutand    schedule 25.03.2012
comment
Мой телефон работает под управлением Android 4.0.3, как и эмулятор.   -  person Glitch    schedule 26.03.2012
comment
Какую плотность/размер экрана вы используете на эмуляторе по сравнению с устройством?   -  person cistearns    schedule 04.04.2012
comment
Зачем беспокоиться о размере кучи, когда ваше приложение работает на переднем плане? за исключением случаев, когда ваше приложение работает как служба   -  person Superbiji    schedule 04.04.2012


Ответы (1)


Система предварительно загрузит системные ресурсы по умолчанию, это не зависит от ресурсов вашего приложения, таких как стандартные Drawables для флажков и переключателей. 10,5 МБ кажутся большими, но есть много системных ресурсов по умолчанию, а изображения становятся больше после сохранения в памяти. Предварительная загрузка не нова, но размер предварительной загрузки в ICS может быть больше. Плотность отображения, вероятно, играет роль в этом наряду с простым добавлением большего количества системных Drawables, предварительно загруженных в ICS.

В настоящее время нет способа уменьшить объем памяти, занимаемой sPreloadedDrawables

К сожалению, нет способа очистить это после запуска процесса приложения для приложений (особенно игр), которые не используют большую часть системных Drawables. В этом случае большой размер ресурсов предварительной загрузки, по-видимому, был ошибкой определенного выпуска (или порта телефона) ICS. В противном случае обычно это небольшой объем памяти, поэтому я сомневаюсь, что когда-либо понадобится такой механизм для уменьшения использования памяти предварительной загрузки.

Если у вас заканчивается память из-за этого кеша, я, вероятно, отправлю отчет об ошибке в Google.

Вы можете проследить процесс предварительной загрузки ресурсов здесь, если вас интересуют более внутренние детали. ZygoteInit.preloadResources

person cistearns    schedule 04.04.2012
comment
Ага. Не будет возможности отключить это — это делается в процессе zygote, который создается один раз и из которого порождаются все процессы приложения. Таким образом, загружаемые ресурсы распределяются между всеми процессами. - person hackbod; 05.04.2012
comment
Спасибо, цистерны. Моя главная проблема заключается в том, что у меня есть пользователи, которые видят это использование памяти и сообщают об этом. Это влияет на мой звездный рейтинг. В моем телефоне используется тот же дисплей, что и в iPhone 4, поэтому он имеет очень высокую плотность (примерно 320 точек на дюйм). На стандартной ICS он будет использовать более 20 МБ, как сообщает Android. Интересно, что после обновления до более поздней сборки он уменьшился примерно до 7 МБ. Так что мне интересно, может ли это быть продуктом плохого стандартного порта ICS? - person Glitch; 05.04.2012
comment
Похоже, это была ошибка, из-за которой во время предварительной загрузки загружалось больше (или больше) элементов, чем предполагалось. @hackbod Я не до конца копался в зиготе, чтобы увидеть, что она использовалась как генератор (очень круто), поэтому я понимаю, почему предварительная загрузка всегда должна происходить. Можно было бы добавить поддержку очистки ресурсов предзагрузки после форка. Но учитывая, что большой размер, похоже, был ошибкой, а обычно он маленький, я сомневаюсь, что это когда-либо понадобится. - person cistearns; 07.04.2012
comment
@hackbod В Android 4.1 в дампе кучи нашего приложения на sPreloadedDrawables по-прежнему приходится около 5 МБ сохраненной памяти. Это считается нормальной суммой? Я также должен добавить, что 2 из этих ресурсов, которые находятся в памяти из-за сильных ссылок из sPreloadedDrawables, имеют размер 1 МБ каждый. Какой из рисунков по умолчанию в Android займет такое место? - person Matthias; 28.02.2013
comment
Это действительно будет зависеть от устройства. Между новыми экранами с высоким разрешением и OEM-производителями, добавляющими настраиваемые чертежи по умолчанию, возможно проникновение больших изображений. - person cistearns; 01.03.2013
comment
смешно предположить, что Google действительно позаботится об отчете об ошибке ... есть еще ошибки 4-5-летней давности, которые не были исправлены, а @hackbod? - person StackOverflowed; 21.01.2015
comment
Ну, это действительно специфическая ошибка телефона, обычно набор предварительной загрузки не очень большой. Хотя мое предложение разрешить освобождение неиспользуемой предварительно загруженной памяти действительно, оно применимо только к подмножеству приложений. Также теоретически, если копирование при записи работает правильно, эта предварительно загруженная память может быть просто разделена, но это предполагает, что они могут гарантировать, что у нее есть собственная страница. Это ломается, если разветвленное приложение когда-либо записывает на ту же страницу памяти, в которой находятся предварительно загруженные ресурсы. Тот факт, что предварительно загруженные ресурсы (и любые другие вещи из Zygote) могут быть на общей странице, — это то, что MAT не может принять во внимание. Счет. - person cistearns; 30.01.2015