public class UserManger {
private static UserManger instance;
private Context context;
private UserManger(Context context) {
this.context = context;
}
public static UserManger getInstance(Context context) {
if (instance == null) {
instance = new UserManger(context);
}
return instance;
}
}
上述代码是典型的容易造成泄漏的单例模式场景
将这个单例模式用于Activity中
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
UserManger userManger = UserManger.getInstance(this);
}
}
此时当我们要回收Activity时因为此Activty中usermanger拥有activity传入的context
导致activity无法回收,这里我们来举个实例观察旋转屏幕后堆中内存的变化
刚进入程序时内存的状况是:
当我们旋转屏幕 activity会被销毁重新创建
初始化内存占用 旋转屏幕后占存我们发现这里占用的内存多了0.06MB,这里可以判定发生了内存泄漏
- 内存泄漏产生的原因是:当一个对象已经不需要再使用了,本该被回收时,而有另外一个正在使用的对象持有它的引用从而就导致,对象不能被回收。这种导致了本该被回收的对象不能被回收而停留在堆内存中,就产生了内存泄漏。
我们之前的猜想正是导致内存泄漏产生的原因
我在两个阶段都进行了内存快照
初始化 旋转屏幕 旋转屏幕发现这时因为屏幕旋转的原因activity销毁重建 之前的activity因为持有UserManger的引用没有被销毁还占用了一部分的内存,内存泄漏正是在UserManger处发生
为了避免这种单例模式泄漏发生,这里我们将application的context传入 再运行一次程序
这里我们将application的context传入 再运行一次程序并翻转
传入application的context发现MainActivty的实例只有1个,另外的已经成功OnDestroy(),成功避免了内存泄漏
此篇文章借鉴http://www.jianshu.com/p/ef9081050f5c 的经验所有实例都经过本人实际操作证实
特写此文感悟,谢谢支持
网友评论