Ошибка Android OutOfMemory при создании растрового изображения - PullRequest
1 голос
/ 18 января 2012

Я получаю ошибку java.lang.OutOfMemoryError: bitmap size exceeds VM budget.

Это происходит при создании растрового изображения с целью рисования линейного графика вручную.

width = display.getWidth() - 10;
height = width * 4 / 5;
Bitmap emptyBmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
Bitmap charty = createMyGraphAndStuff(emptyBmap);

Похоже, что общая выделенная память была около 700 Кбайт, это неоправданное количество.

Я видел другие решения, вызываемые при создании растровых изображений из файла, но здесь я сам генерирую их. Как можно уменьшить объем памяти?

Вот еще немного кода, чтобы дать вам лучшее представление о том, что он делает:

public Bitmap DrawTheGraphAndStuff(Bitmap bitmap, String[] scores)
{
        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);
        Canvas canvas = new Canvas(output);

        drawTheGridLines(canvas);                                   

        plotTheDataPoints(canvas ,  scores ,  "the title" , 0 );    

        canvas.drawBitmap(bitmap, rect, rect, paint);

        return output;
}

Ответы [ 5 ]

6 голосов
/ 18 января 2012

когда происходит OOM, дайте несколько советов:

1. нужно знать позицию возникновения oom, достаточно информации журнала

2. большинство времени занимает процесс растрового изображения, поэтому вынужно знать, сколько изображения об используемой памяти:

по формуле: w * h * every pixel token memory in byte, если Config равно Config.ARGB_8888, то каждый пиксель памяти токена равен 4bytes, если это Config.RGB_565,2bytes.

3. Кроме того, необходимо знать ограничения памяти каждого приложения на вашем устройстве:

   ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
   activityManager.getMemoryClass(); //return the memory size limit in MB

3.Если растровое изображение не использовалось снова, попробуйте recyle()это

4.Если начался процесс растрового изображения, память почти максимальный предел памяти, поэтому используйте adb shell dumpsys meminfo $pid, чтобы проверить использование памяти, также ddms - allocation tracker полезно

1 голос
/ 18 января 2012

Это не проблема, которую нужно решить, это проблема дизайна, которую нужно решить.Вы не можете предполагать что-либо о куче, которая будет доступна вам.Вот несколько вещей, которые могут вам помочь.

  • Одной вещью, которую вы могли бы серьезно рассмотреть, является загрузка сжатой версии растрового изображения: определите объем памяти, доступной в куче, перед загрузкой растрового изображения.Исходя из этого, вычислите размер растрового изображения, которое вы хотите загрузить, вычислите высоту и ширину из этого и затем загрузите растровое изображение.
  • Убедитесь, что вы не пропускаете растровые изображения .Это одна из главных проблем, с которыми сталкиваются люди.Это может происходить множеством способов, от утечки представлений до утечки действий.Чтобы проверить это, профилируйте вашу рабочую память .
  • Когда нет утечек памяти, GC автоматически очищает битовые карты.В устройствах до версии 3.0 вы должны вызывать recycle (), потому что сборщик мусора не выполняет хорошую работу.Это не требуется в устройствах после 3.0.Хотя будьте осторожны, если вы вызовете recycle () для используемого растрового изображения, скажем, в ImageView, вы получите исключение.
1 голос
/ 18 января 2012

В основном перерабатывайте свои растровые изображения, и у вас больше не должно быть этой проблемы. Используйте recycle ().

1 голос
/ 18 января 2012

Если ширина вашего дисплея равна 480, ваше растровое изображение будет 470x376.При 4 байтах на пиксель это 706880 байтов.Единственный способ использовать меньше памяти - уменьшить размер растрового изображения.

0 голосов
/ 18 января 2012

Вы всегда можете попробовать использовать битовые карты с мягкой ссылкой, однако они могут собирать мусор быстрее, чем вам нужно.

...