Duplicated Bitmap Analyzer Task
Clone or download
Latest commit e2e02e3 Dec 12, 2018
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
DuplicatedBitmapAnalyzer add readme Dec 7, 2018
doc add readme Dec 7, 2018
gradle/wrapper add readme Dec 7, 2018
tools add readme Dec 7, 2018
.gitignore add readme Dec 7, 2018
README.md update readme Dec 12, 2018
build.gradle add readme Dec 7, 2018
gradle.properties add readme Dec 7, 2018
gradlew add readme Dec 7, 2018
gradlew.bat add readme Dec 7, 2018
settings.gradle add readme Dec 7, 2018

README.md

Chapter04

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

需要注意的是需要使用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中公布,欢迎大家积极参与!