Я новичок в разработке Android. И в настоящее время я ищу автоматический способ сброса памяти при возникновении ошибки нехватки памяти. Я читал, что добавление -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/some/path к вашим аргументам jvm, чтобы при нехватке памяти он выгружал кучу. Но я не нашел, где его установить. Кто-нибудь это знает? большое спасибо.
как позволить dalvik сбрасывать всю память кучи приложения, когда происходит OOM
Ответы (1)
Указанный вами флаг предназначен для виртуальной машины Oracle, а не для Dalvik.
Эквивалентного флага нет, но вы можете реализовать аналогичное поведение. Метод android.os.Debug.dumpHprofData()
запишет текущий дамп кучи в указанный вами файл. В сочетании с UncaughtExceptionHandler
, установленным Thread.setDefaultUncaughtExceptionHandler()
, вы можете поймать OOM в любом потоке и самостоятельно обрабатывать отчеты. (Только не слишком увлекайтесь... у вас в конце концов закончилась память.)
Вам нужно будет связать свой обработчик с системой Android - см. Также Идеальный способ установить глобальный обработчик необработанных исключений в Android.
А собрал быстрый пример того, как это должно выглядеть.
person
fadden
schedule
03.05.2013
Спасибо, fadden, я последовал вашему пути, но похоже, что глобальный обработчик необработанных исключений не может перехватить исключение OOM, хотя другие исключения, такие как исключение нулевого указателя, могут быть перехвачены. Не уверен, что я что-то пропустил, или этот способ неосуществим.
- person bettermanlu; 06.05.2013
Это может не сработать. Если вам совершенно не хватает памяти, вы можете получить OOM, пытающихся сообщить об OOM. Если вам не удалось выделить что-то умеренно большое (например, растровое изображение), у вас будет достаточно места. Вывод
logcat
должен предоставить некоторые подробности.
- person fadden; 06.05.2013
Это довольно простая демонстрация, создающая статическую хэш-карту, а затем сохраняющая в нее растровые объекты, чтобы сделать ее OOM. фрагмент кода выглядит следующим образом: for (int i = 0; i ‹ 10; i++) { String bitMapIdOOM = bitmapId + . + я; Растровое изображение mBitmapOOM = BitmapFactory.decodeResource(getResources(), R.drawable.bike); sBitmapCache.put(bitMapIdOOM, mBitmapOOM); } logcat показывает, как показано ниже, он запрашивает около 8 Мбайт. Это означает, что у него должно быть достаточно места. E/dalvikvm-heap(11636): Недостаточно памяти при распределении 8294416 байт. @fadden, есть предложения?
- person bettermanlu; 07.05.2013
Другим способом может быть создание отдельного монитора процесса, отслеживающего целевое приложение. Когда происходит OOM, монитор процессов останавливает его и сбрасывает кучу. Но я не уверен, как это реализовать. :-)
- person bettermanlu; 07.05.2013
Ну, вы можете подключить отладчик (например, тот, что является частью Eclipse) и настроить точку останова исключения из меню «Выполнить». Установите прерывание на
OutOfMemoryError
как для перехваченных, так и для неперехваченных исключений. В этот момент вы должны оценить метод dumpHprofData
как выражение (Eclipse может выполнять произвольный код, когда вы остановились в точке останова). Вы также можете попробовать использовать вызов java.lang.Runtime.freeMemory
, чтобы угадать, когда у вас заканчивается память, и сбросить кучу перед OOM.
- person fadden; 07.05.2013
Фадден большое спасибо. Я попробую завтра на Eclipse. Моя цель - найти или написать приложение, которое можно было бы удобно использовать на мобильном телефоне, не требуя провода, соединяющего телефон с компьютером, без исходного кода целевого приложения. Если я хочу написать свое собственное приложение-отладчик, как это делает eclipse, которое запускает другое приложение или просто вторгается в другое работающее приложение, чтобы перехватить его неперехваченное исключение. Является ли это возможным? Если да, то знаете ли вы какой-нибудь материал, на который я могу сослаться? Большое спасибо.
- person bettermanlu; 07.05.2013
Я создал образец кода для исходной идеи и добавил ссылку на него в ответ.
- person fadden; 07.05.2013