We will need to release heap memory because for each application has the limited amount of memory usage of RAM, so we recommended to release memory i.e not require further.
We are discussing in this blog how to release Bitmap allocated memory when further Bitmap not required in the running Application. Bitmap usage large amount of RAM memory, so we have got many times OutOfMemoryError Exception.
On Android 2.3.3 (API level 10) and lower, the backing pixel data for a bitmap is stored in native memory. It is separate from the bitmap itself, which is stored in the Dalvik heap. The pixel data in native memory is not released in a predictable manner, potentially causing an application to briefly exceed its memory limits and crash. As of Android 3.0 (API level 11), the pixel data is stored on the Dalvik heap along with the associated bitmap.
In given code, here I am uploading multiple bitmap images on the server through the multipart request, Image URIs is stored in ImageData class. Now We get the Bitmap Image from the URI and then compress/write Image bytes into ByteArrayOutputStream when all the process has done then We recommended to release allocated memory. because the first bitmap is not GC’ed when we decode the second one. GC will do it later whenever it decides. The recycle() method release the allocated bitmap memory.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
private void getBitmapFromURI(ImageData additionalImage, ByteArrayOutputStream byteArrayOutputStream){ Log.d(TAG, "getBitmapFromURI: " + additionalImage.url); Log.d(TAG, "getBitmapFromURI: " + additionalImage.uri); Bitmap btm = null; try { if(additionalImage.isCamera) { btm = BitmapFactory.decodeFile(additionalImage.url); if(btm != null) { btm.compress(Bitmap.CompressFormat.JPEG, 90, byteArrayOutputStream); btm.recycle(); } } else { btm = MediaStore.Images.Media.getBitmap(getContentResolver(), additionalImage.uri); if(btm != null) { if(btm.getByteCount() < Runtime.getRuntime().freeMemory()) { btm.compress(Bitmap.CompressFormat.JPEG, 90, byteArrayOutputStream); btm.recycle(); }else{ btm = resizeImage(btm); btm.compress(Bitmap.CompressFormat.JPEG, 90, byteArrayOutputStream); btm.recycle(); } } } }catch (IOException e){ e.printStackTrace(); }catch (OutOfMemoryError e){ e.printStackTrace(); }finally { if(btm != null) Log.d(TAG, "getBitmapFromURI: btm" + btm); } } |
Different Android versions have different strategies to release Bitmap memory. for example –
- recycle() usage on lower version.
- BitmapFactory.Options on Android 3.0 and Higher
References: https://developer.android.com/topic/performance/graphics/manage-memory.html