- Как решить проблему java.lang.OutOfMemoryError в Android
- Давайте углубимся в Image Sampling:
- Как управлять памятью вашего приложения: ссылка
- Проверка поведения приложения на Android Runtime (ART)
- Решение проблем сбора мусора (GC)
- Предотвращение проблем JNI
- Как решить проблему java.lang.OutOfMemoryError в Android
- Давайте углубимся в выборку изображений:
- Как управлять памятью приложения: ссылка
- Проверка поведения приложения в Android Runtime (ART)
- Проблемы с сборкой мусора (GC)
- Предотвращение проблем JNI
Как решить проблему java.lang.OutOfMemoryError в Android
Хотя у меня очень маленькое изображение в папке с возможностью рисования, я получаю эту ошибку от пользователей. И я не использую функцию bitmap в коде. По крайней мере намеренно 🙂
В соответствии с этим stackTrace я получаю эту ошибку на этой строке («tv» – это textView):
В чем проблема? Если вам нужна другая информация о коде, я могу добавить ее. Благодаря!
Вы не можете увеличить размер кучи динамически, но вы можете попросить использовать больше с помощью.
В manifest.xml вы можете добавить в свой манифест эти строки, которые он работает для некоторых ситуаций.
Должны ли быть созданы процессы вашего приложения с большой кучей Dalvik. Это относится ко всем процессам, созданным для приложения. Он применяется только к первому приложению, загружаемому в процесс; Если вы используете общий идентификатор пользователя, чтобы позволить нескольким приложениям использовать процесс, все они должны использовать этот параметр последовательно или у них будут непредсказуемые результаты. Большинство приложений не должны этого нуждаться и вместо этого должны сосредоточиться на сокращении общего использования памяти для повышения производительности. Включение этого также не гарантирует фиксированного увеличения доступной памяти, поскольку некоторые устройства ограничены их общей доступной памятью.
Чтобы запросить доступный размер памяти во время выполнения, используйте методы getMemoryClass() или getLargeMemoryClass() .
Если все еще стоит проблема, тогда это также должно работать
Если установлено значение> 1, запрашивает декодер для подвыборки исходного изображения, возвращая меньшее изображение для сохранения памяти.
Это оптимальное использование BitmapFactory.Options.inSampleSize относительно скорости отображения изображения. В документации упоминаются значения, которые имеют мощность 2, поэтому я работаю с 2, 4, 8, 16 и т. Д.
Давайте углубимся в Image Sampling:
Например, не стоит загружать изображение с разрешением 1024×768 пикселей в память, если в конечном итоге оно будет отображаться в миниатюре размером 128×128 пикселей в ImageView .
Чтобы inSampleSize декодер для подвыражения изображения, загрузив меньшую версию в память, установите для inSampleSize значение true в свой объект BitmapFactory.Options . Например, изображение с разрешением 2100 x 1500 пикселей, которое декодируется с помощью параметра inSampleSize 4, создает растровое изображение приблизительно 512×384. Загрузка этого в память использует 0,75 МБ, а не 12 МБ для полного изображения (при условии конфигурации растрового изображения ARGB_8888 ). Ниже приведен метод вычисления значения размера выборки, который представляет собой мощность двух на основе ширины и высоты цели:
Примечание . Значение двух значений рассчитывается, потому что декодер использует конечное значение, округляя до ближайшей мощности в два, согласно документации inSampleSize .
Чтобы использовать этот метод, сначала inJustDecodeBounds декодирование с параметром inJustDecodeBounds установленным в true , передайте параметры и затем снова декодируйте, используя новое значение inJustDecodeBounds а inJustDecodeBounds – false :
Этот метод упрощает загрузку растрового изображения произвольно большого размера в ImageView который отображает миниатюру размером 100×100 пикселей, как показано в следующем примере кода:
Вы можете выполнить аналогичный процесс для декодирования растровых изображений из других источников, заменив соответствующий метод BitmapFactory.decode* мере необходимости.
Я нашел этот код интересным:
Как управлять памятью вашего приложения: ссылка
Не рекомендуется использовать android:largeHeap=»true» Вот выдержка из Google, которая объясняет это,
Однако возможность запросить большую кучу предназначена только для небольшого набора приложений, которые могут оправдать необходимость потреблять больше ОЗУ (например, большое приложение для редактирования фотографий). Никогда не запрашивайте большую кучу просто потому, что у вас закончилась нехватка памяти, и вам нужно быстрое исправление – вы должны использовать ее только тогда, когда вы точно знаете, где находится вся ваша память, и почему ее необходимо сохранить. Тем не менее, даже если вы уверены, что ваше приложение может оправдать большую кучу, вы должны избегать его запроса в любой возможной степени. Использование дополнительной памяти будет в большей степени нарушать общий пользовательский интерфейс, поскольку сбор мусора займет больше времени, а производительность системы может быть медленнее при переключении задач или выполнении других общих операций.
После работы excrutiatingly с out of memory errors я бы сказал, добавив это в манифест, чтобы избежать проблемы с oom, не является грехом
Проверка поведения приложения на Android Runtime (ART)
Время выполнения Android (ART) является средой исполнения по умолчанию для устройств под управлением Android 5.0 (API уровня 21) и выше. Эта среда исполнения предлагает ряд функций, которые повышают производительность и плавность платформы Android и приложений. Вы можете найти более подробную информацию о новых возможностях ART в представлении ART .
Однако некоторые методы, которые работают на Дальвике, не работают на АРТ. Этот документ позволяет вам узнать о том, что нужно посмотреть при переносе существующего приложения для совместимости с АРТ. Большинство приложений должны работать только при работе с АРТ.
Решение проблем сбора мусора (GC)
В Dalvik приложениям часто бывает полезно явно вызвать System.gc (), чтобы вызвать сборку мусора (GC). Это должно быть гораздо менее необходимо для АРТ, особенно если вы вызываете сборку мусора, чтобы предотвратить появление типа GC_FOR_ALLOC или уменьшить фрагментацию. Вы можете проверить, какая среда исполнения используется, вызывая System.getProperty («java.vm.version»). Если АРТ используется, значение свойства «2.0.0» или выше.
Кроме того, в Android Open Source Project (AOSP) разрабатывается компактный сборщик мусора для улучшения управления памятью. Из-за этого вам следует избегать использования методов, несовместимых с уплотнением GC (например, сохранение указателей на данные экземпляра объекта). Это особенно важно для приложений, которые используют интерфейс Java Native Interface (JNI). Дополнительные сведения см. В разделе Предупреждение проблем JNI.
Предотвращение проблем JNI
JNI от ART несколько более строг, чем у Dalvik’s. Особенно полезно использовать режим CheckJNI для обнаружения общих проблем. Если ваше приложение использует код C / C ++, вы должны просмотреть следующую статью:
Кроме того, вы можете использовать встроенную память ( NDK & JNI ), поэтому вы фактически обходите ограничение размера кучи.
Вот несколько сообщений об этом:
Как кэшировать растровые изображения в родной памяти
JNI, чтобы помочь избежать OOM при использовании больших изображений
И вот библиотека, созданная для него:
Вы должны реализовать диспетчер кэша LRU при работе с растровым изображением
Используйте библиотеку уровня, например Universal Image Loader:
Теперь, когда вы работаете с изображениями и большую часть времени с помощью растрового изображения, я использую Glide, который позволяет вам настроить модуль Glide и LRUCache
Я вижу только два варианта:
- У вас есть утечки памяти в приложении.
- У устройств недостаточно памяти при запуске приложения.
Источник
Как решить проблему java.lang.OutOfMemoryError в Android
Хотя у меня очень маленькое изображение размера в папке с возможностью переноса, я получаю эту ошибку от пользователей. И я не использую какую-либо функцию растрового изображения в коде. По крайней мере, преднамеренно:)
В соответствии с этим stackTrace я получаю эту ошибку в этой строке ( “tv” – это textView):
В чем проблема? Если вам нужна другая информация о коде, я могу добавить ее.
Спасибо!
Вы не можете увеличить размер кучи динамически, но вы можете запросить больше использовать с помощью.
в manifest.xml , вы можете добавить в свой манифест эти строки, которые он работает для некоторых ситуаций.
Должны ли быть созданы ваши прикладные процессы с большой кучей Dalvik. Это относится ко всем процессам, созданным для приложения. Он применяется только к первому приложению, загружаемому в процесс; если вы используете общий идентификатор пользователя, чтобы разрешить нескольким приложениям использовать процесс, все они должны использовать эту опцию последовательно или у них будут непредсказуемые результаты. Большинство приложений не должны этого нуждаться и вместо этого должны сосредоточиться на сокращении общего использования памяти для повышения производительности. Включение этого также не гарантирует фиксированного увеличения доступной памяти, поскольку некоторые устройства ограничены их общей доступной памятью.
Чтобы запросить доступный размер памяти во время выполнения, используйте методы getMemoryClass() или getLargeMemoryClass() .
Если все еще стоит проблема, тогда это также должно работать
Это оптимальное использование BitmapFactory.Options.inSampleSize относительно скорости отображения изображения.
В документации упоминаются значения, которые имеют мощность 2, поэтому я работаю с 2, 4, 8, 16 и т.д.
Давайте углубимся в выборку изображений:
Например, его не стоит загружать в память изображение с разрешением 1024×768 пикселей, если оно в конечном итоге будет отображаться в миниатюре размером 128 × 128 пикселей в ImageView .
Чтобы декодер подсуммировал изображение, загрузив меньшую версию в память, установите inSampleSize в true в свой BitmapFactory.Options объект. Например, изображение с разрешением 2100 x 1500 пикселей, декодированное с помощью inSampleSize of 4, создает растровое изображение размером приблизительно 512×384. Загрузка этого в память использует 0,75 МБ, а не 12 МБ для полного изображения (при условии конфигурации растрового изображения ARGB_8888 ). Heres метод для вычисления значения размера выборки, который является мощностью двух на основе ширины и высоты цели:
Примечание: вычисляется мощность двух значений, поскольку декодер использует конечное значение, округляя до ближайшей силы двух, согласно inSampleSize .
Чтобы использовать этот метод, сначала декодируйте с inJustDecodeBounds , установленным на true , передайте параметры через, а затем снова декодируйте, используя новое значение inSampleSize и inJustDecodeBounds , установленное на false :
Этот метод упрощает загрузку растрового изображения произвольно большого размера в ImageView , который отображает миниатюру размером 100×100 пикселей, как показано в следующем примере кода:
Вы можете выполнить аналогичный процесс для декодирования растровых изображений из других источников, заменив соответствующий метод BitmapFactory.decode* по мере необходимости.
Я нашел этот код интересным:
Как управлять памятью приложения: ссылка
Не рекомендуется использовать android:largeHeap=»true» здесь выдержку из Google, которая объясняет это,
Однако способность запрашивать большую кучу предназначена только для небольшой набор приложений, которые могут оправдать необходимость потреблять больше оперативной памяти (например, как большое приложение для редактирования фотографий). Никогда не просите большую кучу просто потому что у вас закончилась нехватка памяти, и вам нужно быстрое исправление – вы должны используйте его только тогда, когда вы точно знаете, где находится вся ваша память и почему он должен быть сохранен. Тем не менее, даже если вы уверены ваше приложение может оправдать большую кучу, вам следует избегать запроса насколько возможно. Использование дополнительной памяти будет все чаще в ущерб общему опыту пользователя, поскольку мусор сбор займет больше времени, а производительность системы может быть медленнее, если переключение задач или выполнение других общих операций.
После работы excrutiatingly с out of memory errors я бы сказал, добавив это в манифест, чтобы избежать проблемы с oom, не является грехом
Проверка поведения приложения в Android Runtime (ART)
Время выполнения Android (ART) – это среда исполнения по умолчанию для устройств под управлением Android 5.0 (API уровня 21) и выше. Эта среда исполнения предлагает ряд функций, которые повышают производительность и плавность платформы Android и приложений. Вы можете найти дополнительную информацию о новых функциях ART в Представлять ART.
Однако некоторые методы, которые работают на Дальвике, не работают на АРТ. Этот документ позволяет вам узнать о том, что нужно посмотреть при переносе существующего приложения для совместимости с АРТ. Большинство приложений должны работать только при работе с ART.
Проблемы с сборкой мусора (GC)
В Dalvik приложениям часто бывает полезно явно вызвать System.gc(), чтобы вызвать сборку мусора (GC). Это должно быть гораздо менее необходимо для АРТ, особенно если вы вызываете сбор мусора, чтобы предотвратить появление типа GC_FOR_ALLOC или уменьшить фрагментацию. Вы можете проверить, какая среда исполнения используется, вызывая System.getProperty( “java.vm.version” ). Если используется АРТ, значение свойства “2.0.0” или выше.
Кроме того, в Android Open-Source Project (AOSP) разрабатывается компактный сборщик мусора для улучшения управления памятью. Из-за этого вам следует избегать использования методов, которые несовместимы с уплотнением GC (например, сохранение указателей на данные экземпляра объекта). Это особенно важно для приложений, которые используют интерфейс Java Native Interface (JNI). Дополнительные сведения см. В разделе Предупреждение проблем JNI.
Предотвращение проблем JNI
ART JNI несколько более строг, чем у Dalvik’s. Особенно полезно использовать режим CheckJNI для обнаружения общих проблем. Если ваше приложение использует код C/С++, вы должны просмотреть следующую статью:
Кроме того, вы можете использовать встроенную память (NDK и JNI), поэтому вы фактически обходите ограничение размера кучи.
Вот несколько сообщений об этом:
и здесь создана библиотека для него:
Я вижу только два варианта:
- У вас есть утечки памяти в приложении.
- У устройств недостаточно памяти при запуске приложения.
Вы должны реализовать диспетчер кэша LRU при работе с растровым изображением
Используйте библиотеку уровней, например Universal Image Loader:
Теперь, когда вы работаете с изображениями и большую часть времени с помощью растрового изображения, я использую Glide, который позволяет вам настроить модуль Glide и LRUCache
Несколько советов по обработке такой ошибки/исключения для приложений Android:
Деятельность и применение имеют такие методы, как:
- onLowMemory
- onTrimMemory Обработайте эти методы, чтобы следить за использованием памяти.
тег в манифесте может иметь атрибут “largeHeap”, установленный в значение “ИСТИНА”, что требует дополнительной кучи для изолированной программной среды приложения
Управление кэшированием в памяти и диском:
- Изображения и другие данные могли кэшироваться в памяти во время работы приложения (локально в действиях/фрагментах и глобально); следует управлять или удалить.
Использование WeakReference, SoftReference создания экземпляров Java, в частности, для файлов.
Если изображений так много, используйте правильную библиотеку/структуру данных, которая может управлять памятью, использовать выборку загруженных изображений, обрабатывать кеширование диска.
Обработать исключение OutOfMemory
Следуйте рекомендациям по кодированию
- Утечка памяти (Не держите все под строгим контролем)
Минимизируйте стек действий, например, количество действий в стеке (не держите все в контексте/активности)
- Контекст имеет смысл, те данные/экземпляры, которые не требуются вне области действия (действия и фрагменты), удерживают их в соответствующем контексте вместо глобального хранения ссылок.
Минимизируйте использование статики, еще много синглетонов.
Позаботьтесь об основных фондах памяти ОС
- Проблемы фрагментации памяти
Источник