Растровые изображения в Android - PullRequest
29 голосов
/ 22 декабря 2009

У меня есть несколько вопросов относительно растровых объектов и памяти и их общей таксономии.

  1. Что такое встроенное или родное растровое изображение?
  2. Чем битовая память отличается от памяти кучи?

Ответы [ 4 ]

33 голосов
/ 22 декабря 2009

Память, которая поддерживает объект Bitmap, выделяется с использованием собственного кода (malloc()), а не ключевого слова Java new. Это означает, что память управляется непосредственно ОС, а не Dalvik.

Единственная реальная разница между собственной кучей и кучей Dalvik состоит в том, что куча Dalvik является сборщиком мусора, а собственная - нет.

Для этих целей здесь нет большой разницы. Когда ваш растровый объект получает сборщик мусора, его деструктор перерабатывает связанную память в собственной куче.

Источник:

32 голосов
/ 23 декабря 2009

Здесь есть одна тонкость: хотя пиксели растрового изображения выделяются в собственной куче, некоторые специальные приемы в Dalvik заставляют его учитывать кучи Java. Это сделано по двум причинам:

(1) Для управления объемом памяти, которое выделяет приложение. Без учета приложение могло бы выделить огромный объем памяти (поскольку сам объект Bitmap очень мал, но может удерживать произвольно большой объем собственной памяти), выходя за пределы кучи 16 МБ или 24 МБ.

(2) Чтобы помочь определить, когда GC. Без учета вы можете размещать и отпускать ссылки, скажем, на 100 растровых объектов; GC не будет работать, потому что эти объекты крошечные, но на самом деле они могут представлять большое количество мегабайт фактических выделений, которые сейчас не собираются GCed своевременно. С учетом этих распределений по куче Java сборщик мусора будет работать, поскольку он считает, что используется память.

Обратите внимание, что во многих отношениях это деталь реализации; весьма вероятно, что это может измениться в будущем, хотя это базовое поведение останется в той или иной форме, поскольку они оба являются важными характеристиками для управления распределением растровых изображений.

12 голосов
/ 18 февраля 2011

Из развертываний в дикой природе, я нашел следующие устройства:

  • Устройства, ограничивающие до 16 МБ кучи Java (растровые изображения практически не ограничены).
  • Устройства с ограничением до 16 МБ (кучи Java + хранилище собственных растровых изображений)
  • Устройства, ограничивающие до 24 МБ кучи Java (растровые изображения практически не ограничены).
  • Устройства с ограничением до 24 МБ (кучи Java + хранилище собственных растровых изображений)

24 МБ, как правило, являются устройствами с высоким разрешением и могут быть обнаружены с помощью Runtime.getRuntime (). MaxMemory (). Сейчас также есть устройства 32 МБ, а некоторые из рутированных телефонов по умолчанию имеют 64 МБ. Раньше я несколько раз путала себя, пытаясь понять, что происходит. Я думаю, что все устройства считают битовые карты в пределе кучи. Но крайне сложно сделать какие-либо обширные обобщения о флоте андроидов.

Это ОЧЕНЬ неприятная проблема на Android и очень запутанная. Этот предел и его поведение плохо документированы, сложны и крайне неинтуитивны. Они также различаются в зависимости от устройства и версии ОС и имеют несколько известных ошибок. Частично проблема заключается в том, что ограничения не точны - из-за фрагментации кучи вы попадете в OOM задолго до фактического ограничения и должны консервативно покинуть мегабайт или два буфера. Хуже того, у меня есть несколько устройств, в которых есть собственный segfault (ошибка на 100% в самом Android), который происходит до того, как вы получите исключение java OOM, что делает вдвойне важным никогда не достигать предела, так как вы даже не можете поймать родная авария. Для более подробной информации о моих расследованиях, проверьте этот пост . В том же посте я объясняю, как измерить использование по сравнению с лимитом и избежать сбоев.

Размер кучи Java - Runtime.getRuntime (). TotalMemory ().

Нет простого способа измерить размер собственного растрового хранилища. Общая собственная куча может быть измерена с помощью Debug.getNativeHeapAllocatedSize (), но только растровые изображения учитываются до предела (я думаю).

0 голосов
/ 28 ноября 2013

Мы можем увеличить размер кучи, используя android:largeheap="true" в вашем файле манифеста. Это решит вашу проблему.

...