首先以这个例子链接地址:(https://github.com/lzyzsd/MemoryBugs)
通过查看onClick的代码知道了程序的运行逻辑,startB()是开启一个新的Activity,startAllocationLargeNumbersOfObjects()是进行大量对象的创建。运行模拟器,效果展示如下:
看看点击之后会通知栏会出现如图的提示:
既然static有问题,那就直接把static去掉,把sTextView变成非静态的就可以了。但是这里面还存在一个不易被发现的内存泄漏行为:
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
System.out.println("post delayed may leak");
}
}, 5000);
这里开启了一个延时的线程,5000ms似乎没有问题,但是增大后我们可以看到LeakCanary会出现提示匿名接口Runnable持有activity的引用;这时候我们要使用WeakReference来对代码进行修改,即实现弱引用,保证可以引用的对象可以被及时垃圾回收;
public static class MyRunnable implements Runnable{
public final WeakReference<MainActivity> mMainActivityWeakReference;
public MyRunnable(MainActivity activity) {
mMainActivityWeakReference = new WeakReference<>(activity);
}
@Override
public void run() {
System.out.println("post delayed may leak");
}
}
但是更改后问题依然存在,但是这次好像和Handler有关,所以将Handler也使用WeakReference进行一下改造
public static class MyHandler extends Handler {
public final WeakReference<MainActivity> mMainActivityWeakReference;
public MyHandler(MainActivity activity) {
mMainActivityWeakReference = new WeakReference<>(activity);
}
}
再来运行一下我们的程序,这次没有任何内存泄漏的提示了。
- 接下来看StartAllocation,连续点击后我们借助Allocation Tracking可以看到内存抖动的现象:
通过Android Studio给我们提供的Allocation Tracking工具进行分析,我们可以看到很多Rect和StringBuilder对象的创建。改进方案是把Rect对象的创建放到成员变量中在onCreate中进行初始化,把String对象创建好,这样就不会重复创建了。
更改完成后,我们再次运行,问题解决了!
大家可以参考这位大神更详细的解释:(http://www.jianshu.com/p/c53101db112e)
1980

被折叠的 条评论
为什么被折叠?



