Мне весьма любопытен вопрос об управлении памятью операционной системы Android, поэтому я надеюсь получить достаточно подробный ответ по этой теме.
Что я хотел бы знать:
- Какой максимальный объем памяти (в мегабайтах / в процентах от общего объема ОЗУ) может использовать приложение Android (которое не является системным приложением)?
- Есть ли различия между версиями Android ?
- Есть ли какие-либо различия в отношении производителя устройства?
И, самое главное:
- Что считается / от чего зависит, когда речь заходит о системе, определяющей, сколько ОЗУ приложение может использовать во время выполнения (при условии, что максимум памяти для приложения не является статическим числом)?
Что я слышал до сих пор (до 2013 года):
- Ранние устройства Android имели ограничение на 16 МБ на приложение
- Позже эта крышка увеличилась до 24 МБ или 32 МБ
Что делает меня очень любопытным:
Оба эти предела очень низкие.
Я недавно загрузил диспетчер задач Android, чтобы проверить оперативную память моих устройств. Что я заметил, так это то, что есть приложения, использующие около 40-50 мегабайт оперативной памяти, что, безусловно, превышает упомянутое максимальное использование оперативной памяти, скажем, 32 МБ. Так как же Android определяет, сколько ОЗУ может использовать приложение? Как это возможно, что приложения превышают этот лимит?
Кроме того, я заметил, что некоторые мои приложения аварийно завершают работу (убивают системой?) С исключением OutOfMemoryException при использовании около 30-40 мегабайт. С другой стороны, у меня на телефоне работают приложения, использующие 100 МБ и более через некоторое время (возможно, из-за утечек памяти), которые не вылетают и не убиваются. Так что, очевидно, это также зависит от самого приложения, когда дело доходит до определения того, сколько ОЗУ можно сэкономить. Как это возможно? (Я провел свои тесты с HTC One S с 768 МБ ОЗУ)
Отказ от ответственности: Я НЕ связан ни с каким приложением Android Task Manager.
источник
Это конец 2018 года, так что все изменилось.
Прежде всего: запустите приложение и откройте вкладку Android Profiler в Android Studio. Вы увидите, сколько памяти он потребляет, вы будете удивлены, но он может выделить много оперативной памяти.
Также здесь есть отличная статья в официальных документах с подробными инструкциями о том, как использовать Memory Profiler, которая может дать вам всесторонний обзор управления вашей памятью.
Но в большинстве случаев вам будет достаточно обычного Android Profiler.
Обычно приложение запускается с 50 МБ памяти, но при загрузке некоторых фотографий в память мгновенно увеличивается до 90 МБ. Когда вы открываете Activity с помощью ViewPager с предварительно загруженными фотографиями (по 3,5 МБ каждая), вы можете легко получить 190 МБ за несколько секунд.
Но это не значит, что у вас есть проблемы с управлением памятью.
Лучший совет, который я могу дать, - следовать рекомендациям и рекомендациям, использовать лучшие библиотеки для загрузки изображений (Glide, Picasso), и все будет в порядке.
Но если вам нужно что-то адаптировать, и вам действительно нужно знать, сколько памяти вы можете выделить вручную, вы можете получить полную свободную память и рассчитать заранее определенную часть (в%) из нее. В моем случае мне нужно было кэшировать расшифрованные фотографии в памяти, поэтому мне не нужно расшифровывать их каждый раз, когда пользователь просматривает список.
Для этого вы можете использовать готовый к использованию класс LruCache . Это класс кеша, который автоматически отслеживает, сколько памяти выделяют ваши объекты (или количество экземпляров), и удаляет самые старые, чтобы сохранить последние по истории их использования. Вот отличный урок о том, как его использовать.
В моем случае я создал 2 экземпляра кешей: для больших пальцев и вложений. Сделайте их статичными с одноэлементным доступом, чтобы они были доступны во всем приложении.
класс кеша:
Вот как я вычисляю доступную свободную оперативную память и сколько я могу укусить из нее:
И вот как я использую его в адаптерах для получения кэшированного изображения:
и как я устанавливаю его в кэш в фоновом потоке (обычный AsyncTask):
Мое приложение предназначено для API 19+, поэтому устройства не устарели, и в моем случае эти части доступной оперативной памяти достаточно хороши для кэширования (1% и 3%).
Интересный факт: Android не имеет API или других хаков, чтобы получить объем памяти, выделенный для вашего приложения, он рассчитывается на лету на основе различных факторов.
PS Я использую поле статического класса для хранения кэша, но в соответствии с последними рекомендациями Android рекомендуется использовать для этой цели компонент архитектуры ViewModel .
источник
Ограничения памяти для каждого приложения указаны здесь в зависимости от размера экрана и версии Android: https://drive.google.com/file/d/0B7Vx1OvzrLa3Y0R0X1BZbUpicGc/view?usp=sharing
Источник: Загрузки для Android-совместимости http://source.android.com/compatibility/downloads.html ; Документ определения совместимости (CDD), раздел «Совместимость виртуальных машин» или «Совместимость во время выполнения»
источник