内存泄漏查找 (酷我音乐)
这道题想考察什么?
- 是否了解android 内存泄漏产生的原因
- 是否了解内存泄漏的背景。
考察的知识点
- android内存泄漏产生的产生场景
- android 内存泄漏的触发机制
- android 内存泄漏的原因
考生应该如何回答
方式一、
把app的堆内存空间想成了一个杯子,内存就是里面的水。当你的app启动后,系统会分配给app一个堆空间,起始不会很大比如是32M(根据你的app启动时的内存申请为准)随着程序的运行对象的创建越来越多,系统不断加内存分配:32M -> 64M -> ,而GC回收则会定时扫描内存,发现不被引用的对象即可回收。
此时如果有某个Activity持有某个引用,在onDestroy时还不把这个引用设为null,那么返回进入退出这个界面,Activity就会创建很多次从而存在多个实例,导致堆内存直升不降!这就叫做内存泄漏。
方式二、当你的app在使用中莫名崩溃,如果是OOM那么会有如下日志:
ActivityManager manager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
int heapSize = manager.getMemoryClass();
int maxHeapSize = manager.getLargeMemoryClass();
- heapSize是设备分配给app的最大堆内存
- maxHeapSize 是当配置了android:largeHeap=“true” 才有的最大堆内存,一般是heapSize的2-3倍
方式三、用AndroidStudio自带的内存分析工具分析,点击Dump Java Heap:
会在代码区 生成当前时间点的 .hprof格式文件,里面当前的每个对象 内存占用情况,我们现在怀疑ViewDefectPhotoActivity 可能内存泄漏 看一下:ViewDefectPhotoActivity 确实占用了很高的内存 而且有8个实例化对象,足以证明它有内存泄漏,随便点击其中一个,发现都和EditDefectActivity的内部类 ShowEditDefectHelper有关。而且ShowEditDefectHelpe前面带有 黄蓝三角树 这个图标表示,他可以被GC访问到,也就是无法回收:
总结:
- 如何知道你的app上限值heapSize是多少
- 什么情况导致无法GC
- 怎么复现是哪个界面内存泄漏。内存泄漏不是一眼就能看出来了,需要测试人员配合。当然还有一个办法就是facebook的开源库:leakcanary,具体使用我不多介绍了。它是一个apk安装在手机上可以直接列出内存泄漏的Activity,但是有一定误报几率。