Appearance
bitmap-memory-demo
对应知识库文档:ART GC 机制、Bitmap 内存演进与大图优化 上级章节:性能、测试、排障
1. 实验目标
用最小 Android 实现验证 Bitmap 内存五个知识点(对应 docs/07-performance-testing-debug/08),代码合成一张 2000×2000 PNG(ARGB_8888 解码 ≈ 16MB)逐项打印内存数字:
- Config 对比:同一张图按
ARGB_8888/RGB_565解码,打印allocationByteCount,验证"内存 = 宽×高×每像素字节数、565 正好减半" - inSampleSize 降采样:
inJustDecodeBounds只读宽高 →calculateInSampleSize(最大的 2 的幂)→ 解码,验证"省 sample² 倍、结果是 2 的幂近似" - inBitmap 复用:
inMutable=true首次解码后,把同一对象作为inBitmap再解一次,验证"同一内存地址复用" - 大图检测:控件 300×300,整图解码时判定"超过控件 2 倍"告警,降采样后再查
- RegionDecoder 分块:
newInstance只读头部不载像素,decodeRegion(500×500)只解码视口,内存恒定 = 视口大小
2. 工程要点
- 内存公式:
宽 × 高 × 每像素字节数(ARGB_8888=4B、RGB_565=2B) inSampleSize必须 2 的幂;calculateInSampleSize循环取"宽高各除以 2 后仍 ≥ 目标"的最大值inBitmap复用前提:旧图容量 ≥ 新图、inMutable=true、config 兼容BitmapRegionDecoder.newInstance只解析头部;decodeRegion(rect)按需随机读文件对应区域
3. 运行方式
bash
cd labs/android/host
export JAVA_HOME=$(/usr/libexec/java_home -v 17) # 需要 JDK 17
./gradlew installDebug设备/模拟器打开 Android Host → 打开 Bitmap 内存 (Config/采样/复用/大图) 实验室。页面直接打印五个实验的内存数字与结论。
4. 可能输出(节选)
【1. Config 对比】内存 = 宽 x 高 x 每像素字节数
ARGB_8888: 2000x2000 -> 15.3 MB
RGB_565 : 2000x2000 -> 7.6 MB(正好一半)
【2. inSampleSize】原图 2000x2000,目标 500x500
sample=4 -> 解码 500x500 = 1.0 MB(省 16 倍)
【3. inBitmap 复用】首次分配 15.3 MB
复用解码 2000x2000 = 15.3 MB(未新增分配)同一对象复用成功: true
【4. 大图检测】控件 300x300,解码 2000x2000 = 15.3 MB
⚠ 超过控件 2 倍,未降采样,告警!
【5. BitmapRegionDecoder】newInstance 只读头部: 2000x2000
decodeRegion(500x500) -> 只解码 500x500 = 1.0 MB(内存恒定 = 视口)5. 观察重点
- Config 差正好 2 倍;565 无 Alpha、渐变可能色带。
- inSampleSize 是 2 的幂近似;非 2 的幂会被向下取整。
- RegionDecoder 的
newInstance不载像素,decodeRegion按需解码——视口外像素不进内存。
代码入口
- BitmapMemoryDemoActivity.kt —— 演示页面(入口
BitmapMemoryDemoActivity,由MainActivity的openBitmapMemoryLabButton拉起)。 - 依赖:纯
android.graphicsAPI,无第三方依赖。