Chapter04

Introduction: Duplicated Bitmap Analyzer Task
More: Author   ReportBugs   
Tags:

终于迎来了第一个课后作业,今天我们尝试通过分析内存文件 hprof 快速判断内存中是否存在重复的图片,并且将这些重复图片的 PNG、堆栈等信息输出。

hprof 文件格式可以参考 doc 西面的 manual.html 文件

需要注意的是需要使用 8.0 以下的机器,因为 8.0 以后 Bitmap 中的 buffer 已经放到 native 内存中了

下面是一个结果的样例:

"duplcateCount":2,
"stacks":[
     [
         "static com.sample.launcher.controller.LauncherController mLauncherView(0x1349c400)",
         "com.sample.launcher.view.LauncherView mHeaderView(0x1349bc00)",
         "com.sample.homepage.header.HomePageHeaderView mSearchAndAddressBar(0x13118c00)",
         "android.widget.ImageView mDrawable(0x131f9400)",
         "android.graphics.drawable.BitmapDrawable mBitmapState(0x13799b80)",
         "android.graphics.drawable.BitmapDrawable$BitmapState mBitmap(0x13b0f4d8)",
         "android.graphics.Bitmap instance"
     ],
     [
         "static com.sample.resources.ResourceCache cachePool(0x12d32380)",
         "com.sample.resources.ResourceCache table(0x12c30250)",
         "array java.util.HashMap$HashMapEntry[] [130](0x14724000)",
         "java.util.LinkedHashMap$LinkedHashMapEntry after(0x130ed420)",
         "java.util.LinkedHashMap$LinkedHashMapEntry value(0x1361f780)",
         "com.sample.resources.ResourceCache$CacheSoftReference T(0x1361f760)",
         "android.graphics.drawable.BitmapDrawable mBitmapState(0x136a2d30)",
         "android.graphics.drawable.BitmapDrawable$BitmapState mBitmap(0x13971708)",
         "android.graphics.Bitmap instance"
     ]
],
"bufferHash":"4e2b2a183d1b48bcf2b12af45afdbc12",
"width":60,
"height":60,
"bufferSize":14400

bufferHash 对应的重复图片:

实现提示

hprof 文件分析我们有两个实现方法:

  1. 参考 Android Profiler 中perflib的分析源码,其中重复 Bitmap 的代码是DuplicatedBitmapAnalyzerTask
  2. 我们也可以使用 sqaure 的HAHA库,其中核心方法为:
// 打开 hprof 文件
final HeapSnapshot heapSnapshot = new HeapSnapshot(hprofFile);
// 获得 snapshot
final Snapshot snapshot = heapSnapshot.getSnapshot();
// 获得 Bitmap Class
final ClassObj bitmapClass = snapshot.findClass("android.graphics.Bitmap");
// 获得 heap, 只需要分析 app 和 default heap 即可
Heap heap = snapshot.getHeaps();
// 从 heap 中获得所有的 Bitmap 实例
final List<Instance> bitmapInstances = bitmapClass.getHeapInstances(heap.getId());
// 从 Bitmap 实例中获得 buffer 数组
ArrayInstance buffer = HahaHelper.fieldValue(((ClassInstance) bitmapInstance).getValues(), "mBuffer");

整个思路就是通过"mBuffer"的 hash 值判断哪些 Bitmap 是重复的。

提交方法

整个提交方法如下:

  1. 完善 DuplicatedBitmapAnalyzer 项目
  2. 注明极客时间的账号 + 实现原理与心得体会
  3. 发送 pull request 到本 repo

奖励

根据项目质量和提交 pull request 的时间,抽取部分同学送上经典书籍。

最终结果也会在极客时间和 repo 中公布,欢迎大家积极参与!

Support Me
Apps
About Me
Google+: Trinea trinea
GitHub: Trinea