Ограничение ОЗУ в Android приложениях?

Есть задача отображать много кастомных списков с изображениями размером 400x200(таких изображений порядка 500 шт.), соответственно, для адекватного отображения всех этих списков, требуется подгрузить все эти изображения в память. Были так же и крупные изображения, но их, все же, было решено грузить с SD носителя, что никак нельзя сделать с пунктами списков. Иначе же, эта подгрузка становится очень заметной. Возможно, я что то не так делаю, что скорее всего, но проблема поднялась сама собой. При открытии множетсва пунктов, приложение вылетает вот с таким логом:
01-19 10:47:53.554: D/dalvikvm(4992): GC_BEFORE_OOM freed <1K, 11% free 57601K/64519K, paused 32ms

01-19 10:47:53.554: E/dalvikvm-heap(4992): Out of memory on a 5808016-byte allocation.

01-19 10:47:53.554: I/dalvikvm(4992): «AsyncTask #4» prio=5 tid=14 RUNNABLE

01-19 10:47:53.554: I/dalvikvm(4992): | group=«main» sCount=0 dsCount=0 obj=0x419a07e0 self=0x1ef45f0

01-19 10:47:53.554: I/dalvikvm(4992): | sysTid=5009 nice=10 sched=0/0 cgrp=bg_non_interactive handle=32172032

01-19 10:47:53.554: I/dalvikvm(4992): | schedstat=( 3002593976 773101830 3985 ) utm=284 stm=15 core=1

01-19 10:47:53.554: I/dalvikvm(4992): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)

01-19 10:47:53.554: I/dalvikvm(4992): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:582)

01-19 10:47:53.554: I/dalvikvm(4992): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:638)

01-19 10:47:53.554: I/dalvikvm(4992): at ftp27.apps.cImageManager.downloadImage(cImageManager.java:199)

01-19 10:47:53.554: I/dalvikvm(4992): at ftp27.apps.cImageManager.access$2(cImageManager.java:179)

01-19 10:47:53.554: I/dalvikvm(4992): at ftp27.apps.cImageManager$3.doInBackground(cImageManager.java:223)

01-19 10:47:53.554: I/dalvikvm(4992): at ftp27.apps.cImageManager$3.doInBackground(cImageManager.java:1)

01-19 10:47:53.554: I/dalvikvm(4992): at android.os.AsyncTask$2.call(AsyncTask.java:264)

01-19 10:47:53.554: I/dalvikvm(4992): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)

01-19 10:47:53.554: I/dalvikvm(4992): at java.util.concurrent.FutureTask.run(FutureTask.java:137)

01-19 10:47:53.554: I/dalvikvm(4992): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)

01-19 10:47:53.554: I/dalvikvm(4992): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)

01-19 10:47:53.554: I/dalvikvm(4992): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)

01-19 10:47:53.554: I/dalvikvm(4992): at java.lang.Thread.run(Thread.java:856)

01-19 10:47:53.554: D/skia(4992): — decoder->decode returned false

01-19 10:47:53.562: W/dalvikvm(4992): threadid=12: thread exiting with uncaught exception (group=0x40c031f8)

01-19 10:47:53.570: I/Process(4992): Sending signal. PID: 4992 SIG: 9


Как же обойти сие ограничение?
  • Вопрос задан
  • 12864 просмотра
Решения вопроса 1
@mihaildemidoff
Данное ограничение можно обойти тремя методами.

1) Можно заставить ОС думать, что ваше приложение использует намного меньше памяти, чем есть на самом деле(к сожалению сейчас не могу найти статью с решением). Но это решение является наихудшим из вариантов, если вкратце, память все равно не бесконечна, необходимо правильно ей управлять.

2) Можно в AndroidManifest.xml в application задать android:largeHeap=«true», количество памяти выделенное приложению будет увеличено, но этот вариант опять же подходит для самых необычных случаев, например когда в памяти нужно хранить один большой кусок неразрывных данных.
developer.android.com/guide/topics/manifest/application-element.html

3) Самый правильный вариант по моему мнению, следующий: в памяти должны быть только видимые изображения, все остальные изображения стоит выгружать из памяти(кстати, не забудьте делать recycle на битмапе). Изображения с флеш карты подтягиваются довольно быстро.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@vovkab
Полно же загрузчиков, которые сами все делают, и на карту сохранят и в памяти будут держать столько сколько нужно, вам только нужно передавать ему урл нужной картинки:
1. пример от Google:
developer.android.com/training/displaying-bitmaps/index.html
developer.android.com/shareables/training/BitmapFun.zip

2. Universal-Image-Loader
github.com/nostra13/Android-Universal-Image-Loader

3. и еще один:
wuman.github.com/AndroidImageLoader/

На самом деле их очень много разных, так что выбирайте на любой вкус и цвет.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы