Android Bitmap的内存分配是在Dalvik Heap而不是Native Heap
最近一直在查内存泄露问题,发现Bitmap是最容易出现内存泄露的,然后查看源码以及资料一下颠覆了我的认知观,首先以上结论是建立在Android2.3以后的版本。
首先开撸:我以ImageView --->setBackgroundResource()开始
@RemotableViewMethod
public void setBackgroundResource(int resid) {
if (resid != 0 && resid == mBackgroundResource) {
return;
}
Drawable d = null;
if (resid != 0) {
d = mContext.getDrawable(resid);
}
setBackground(d);
mBackgroundResource = resid;
}
1、上面通过Context中getDrawable(int resid)获得Drawabla
public final Drawable getDrawable(int id) {
return getResources().getDrawable(id, getTheme());
}
2、通过Context中getDrawable(int id)这个方法获取Drawable
@Nullable
public Drawable getDrawable(int id, @Nullable Theme theme) throws NotFoundException {
.....................
final Drawable res = loadDrawable(value, id, theme);
.....................
return res;
}
3、调用Resources中的loadDrawable(TypedValue value , int id , Theme theme);
这里面有两套逻辑:这个方法中使用了缓冲技术,首先是查找缓存中是否有数据?如果是执行如下:创建Drawable
if (cs != null) {
final Drawable clonedDr = cs.newDrawable(this);
4、如果没有,执行如下:
private Drawable loadDrawableForCookie(TypedValue value, int id, Theme theme) {
......................
dr = Drawable.createFromResourceStream(this, value, is, file, null);
..........................
}
Bitmap bm = BitmapFactory.decodeResourceStream(res, value, is, pad, opts);
5、通过调用BitmapFactory.decodeStream()这个方法,通过方法可以看出调用最后进入了nativeDecodeAsset()进入了JNI层,这个就是迷惑我的地方,自认为是申请在Native层 !!!!下面让我来揭开这个神秘的面纱!
public static Bitmap decodeStream(InputStream is, Rect outPadding, Options opts) {
.........................
bm = nativeDecodeAsset(asset, outPadding, opts);
..............
return bm;
}
6、我们进入下面这个目录查看:
Graphics.cpp
Z:\P_2016.01.18_XRobot_base_OneAndroid\frameworks\base\core\jni\android\graphics
7、JNI代码如下:看到真实面纱没?惊讶没!反正我惊讶了!原来JNI创建Bitmap又回到了JAVA层,通过NewObject就明白了
jobject GraphicsJNI::createBitmap(JNIEnv* env, SkBitmap* bitmap, jbyteArray buffer,
int bitmapCreateFlags, jbyteArray ninePatchChunk, jobject ninePatchInsets, int density)
{
.......................
jobject obj = env->NewObject(gBitmap_class, gBitmap_constructorMethodID,
reinterpret_cast<jlong>(bitmap), buffer,
bitmap->width(), bitmap->height(), density, isMutable, isPremultiplied,
ninePatchChunk, ninePatchInsets);
................
}
故Bitmap不及时回收是Dalvik Heap容易内存泄露,而不是Native Heap。