Android 2.2 (API level 8)及之前的版本,垃圾回收(gc)时,app线程是暂停的,这会影响app的性能体验
Android 2.3修改了这个问题,gc变为并行发生的。对于Bitmap来说,当没有被引用时,内存是被回收的。
Android 2.3.3(API level 10)及之前版本,Bitmap的图像像素点是存放在native memory中的,Java中的Bitmap结构是存放在虚拟机堆中,也就是说两者是分开存储的。(jacksonke:native memory是需要手动去回收的,java程序员很容易遗忘,或者程序没写好,很容易出现内存不够的现象)
释放图像像素内存,需要用到Bitmap#recycle()
Android 3.0 之后,图像像素数据也存放在虚拟机堆中。
android碎片化就是这般严重 ^ - ^
Android 3.0 除了图像像素数据存放在虚拟机堆中,还可以复用Bitmap的内存,这样可以省去申请内存和释放内存的时间。这需要设置BitmapFactory.Options.inBitmap,同时还需要满足点额外的条件
* 4.4之前要求图像的height, width, 都要相同,同时要求
inSampleSize == 1
。
* 4.4及之后的版本要求,新的图像内存占用小于旧图像即可使用。
static boolean canUseForInBitmap( Bitmap candidate, BitmapFactory.Options targetOptions) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { // From Android 4.4 (KitKat) onward we can re-use if the byte size of // the new bitmap is smaller than the reusable bitmap candidate // allocation byte count. int width = targetOptions.outWidth / targetOptions.inSampleSize; int height = targetOptions.outHeight / targetOptions.inSampleSize; int byteCount = width * height * getBytesPerPixel(candidate.getConfig()); return byteCount <= candidate.getAllocationByteCount(); } // On earlier versions, the dimensions must match exactly and the inSampleSize must be 1 return candidate.getWidth() == targetOptions.outWidth && candidate.getHeight() == targetOptions.outHeight && targetOptions.inSampleSize == 1; } /** * A helper function to return the byte usage per pixel of a bitmap based on its configuration. */ static int getBytesPerPixel(Config config) { if (config == Config.ARGB_8888) { return 4; } else if (config == Config.RGB_565) { return 2; } else if (config == Config.ARGB_4444) { return 2; } else if (config == Config.ALPHA_8) { return 1; } return 1; }