Bitmap 内存分布
static sk_sp<Bitmap> allocateHeapBitmap(size_t size, const SkImageInfo& info, size_t rowBytes) {
void* addr = calloc(size, 1);
if (!addr) {
return nullptr;
}
return sk_sp<Bitmap>(new Bitmap(addr, size, info, rowBytes));
}
android::Bitmap* GraphicsJNI::allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap,
SkColorTable* ctable) {
const SkImageInfo& info = bitmap->info();
if (info.colorType() == kUnknown_SkColorType) {
doThrowIAE(env, "unknown bitmap configuration");
return NULL;
}
size_t size;
// 计算bitmap 需要占用的内存
if (!computeAllocationSize(*bitmap, &size)) {
return NULL;
}
// 通过jni 像java虚拟机申请一块内存
jbyteArray arrayObj = (jbyteArray) env->CallObjectMethod(gVMRuntime,
gVMRuntime_newNonMovableArray,
gByte_class, size);
if (env->ExceptionCheck() != 0) {
return NULL;
}
SkASSERT(arrayObj);
jbyte* addr = (jbyte*) env->CallLongMethod(gVMRuntime, gVMRuntime_addressOf, arrayObj);
if (env->ExceptionCheck() != 0) {
return NULL;
}
SkASSERT(addr);
android::Bitmap* wrapper = new android::Bitmap(env, arrayObj, (void*) addr,
info, rowBytes, ctable);
// 实际的native 信息给 wrapper
wrapper->getSkBitmap(bitmap);
// since we're already allocated, we lockPixels right away
// HeapAllocator behaves this way too
bitmap->lockPixels();
return wrapper;
}
结论 :
Android < 8.0 之前 Bitmap 内存在java 堆内存中 ,内存申请首先Java堆内存大小限制 Android >= 8.0 Bitmap 内存在 Native内存中 ,内存不受限制,受系统内存大小
查看java 堆内存大小和Native 对内存
Java堆内存
private fun printMemoryInfo(){
Runtime.getRuntime().also {
Log.e("应用可以分配最大内存限制","${it.maxMemory().toM()}")
Log.e("应用当前分配内存 ","${it.totalMemory().toM()}")
Log.e("应用剩余内存 ","${it.freeMemory().toM()}")
Log.e("应用已用内存 ","${it.totalMemory().toM().minus(it.freeMemory().toM())}")
}
}
Native 堆内存
private fun printNativeMemoryInfo(){
// Native 已经使用了多少
"${Debug.getNativeHeapAllocatedSize().toM()}".logE("Native 已使用")
// Native 还剩余多少
"${Debug.getNativeHeapFreeSize().toM()}".logE("Native 剩余内存")
// Native 堆本身内存大小
"${Debug.getNativeHeapSize().toM()}".logE("Native 总内存大小")
}