Skip to content

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.graphics API,无第三方依赖。

对应知识库文档 ​

站点构建时间:2026/8/24 23:43:17