bug项目地址:https://github.com/lzyzsd/MemoryBugs
所用到的工具:AS1.5+, Memory monitor, Allocation tracker, Heap viewer, Leak canary
1.Memory monitor 可以监测到应用的实时内存使用情况,可以方便观测到内存的变化
2.Allocation tracker 记录某个时段内应用所有的内存分配行为,可以方便看到应用产生了多少对象
3.Heap viewer 可以为某个时刻的应用内存堆栈生成一次快照,方便分析
4.Leap canary 集成到程序中,在程序运行过程中提示潜在的内存泄漏点
一、首先浏览一遍代码发现以下问题
1.TextView及Toast显示的文本没有写在String文件里。
2.startAllocationLargeNumbersOfObjects()这个方法中每次循环都会产生一个Rect实例是多余的,会吃内存。MyView的onDraw()方法也存在此问题。
3.Handler mHandler = new Handler(...的方式,mHandler会持有当前Activity的一个引用,在某些情况下会出现内存泄漏。
4.startB()方法中,先执行finish(),然后又用mHandler.postDelay的方式,执行一个延时操作,可能会有问题。
二、使用工具
1.边运行程序边观察Memory monitor。检测到在点击“STARTALLOCATION"后,内存使用出现锯齿状抖动。
2.在点击“STARTALLOCATION”前,打开Allocation tracker,抖动结束后停止tracker。查看生成的文件,发现产生了许多Rect及StringBuilder对象。
3.点击”STARTACTIVITYB“,过5秒后Leap canary提示有内存泄漏。查看信息,是MainActivity中的sTextView造成的,因为静态变量不会被GC回收,在MainActivity finish掉后,由于sTextView仍持有一个引用,故MainActivity的实例仍存在。
4.将sTextView在onDestory中释放掉,把mHandler.postDelay()中的延时改为10秒,然后点击”STARTACTIVITYB“,过一会Leap canary又提示有内存泄漏(果然有问题)。遂用之前教的初始化Handler的方法,在Handler中持有当前Activity的一个弱引用。问题解决。