Я разрабатываю Android-игру, состоящую из многих изображений как спрайтов.
Когда я загружаю изображения следующим образом:
public static Bitmap loadBitmap(int resId) {
return BitmapFactory.decodeResource(getResources(), resId, options);
}
все работает отлично.
Когда я пытаюсь масштабировать down- или up- масштабировать растровое изображение с помощью этого кода:
public static Bitmap loadBitmap(int resId) {
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), resId, options);
Matrix matrix = new Matrix();
matrix.postScale(0.8f, 0.8f);
Bitmap scaledBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
bitmap.recycle();
bitmap = null;
return scaledBitmap;
}
приложение вылетает со следующим исключением:
2211840-byte external allocation too large for this process.
Out of memory: Heap Size=4935KB, Allocated=2549KB, Bitmap Size=18463KB
VM won't let us allocate 2211840 bytes
Почему масштабирование вызывает исключение OutOfMemory? Я даже пытаюсь переработать исходное изображение, чтобы сохранить некоторое пространство. Я не использую Bitmap.createScaledBitmap(...)
намеренно, так как этот метод делает утечку памяти внутренне (как объясняется в других онлайн-ресурсах).
Спасибо заранее,
Златко
Вероятно, вы очень близко к пределу памяти. Похоже, вы создаете довольно большой растровый рисунок (и я не уверен, почему вы делаете его того же размера, что и исходное растровое изображение). Из журнала вы использовали 25 МБ распределений Java и 18 МБ распределений растровых изображений, поэтому вы в основном правы против предела кучи 48 МБ.
Также я думаю, что очень маловероятно, что createScaledBitmap() утечки. Все, что он делает, это в основном то, что вы здесь делаете.
Вам следует попытаться использовать переменную "inSampleSized" в классе BitmapFactory.Options. Это будет масштабироваться без использования избыточной памяти.
http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html#inSampleSize
Я думаю, вы действительно близки к пределу кучи. В вашей функции вы в основном создаете второй битмап, что примерно приводит к удвоению вашей памяти (битмапы очень большие). Если вы находитесь на ОС раньше, чем Honeycomb, это также вводит в заблуждение, чтобы посмотреть на значения памяти, которые где-то распечатываются. iirc, битмапы хранятся непосредственно в куче системной памяти, тогда как все остальные хранятся на куче vm (и это значения, которые вы видите → 2,5 МБ). Тем не менее, память для распределений битмапа также учитывается для ограничения кучи памяти.:/
Я предлагаю вам ознакомиться с этим сеансом ввода-вывода Google: http://www.youtube.com/watch?v=_CruQY55HOk
Я думаю, что ваша проблема может быть решена только путем уменьшения разрешения вашего растрового изображения или с помощью некоторой функции масштабирования, которая не создает экземпляр нового растрового изображения и не изменяет существующий (например, тот, который указан AmandeepGrewal).