(1)static內(nèi)存泄漏
1俏拱、static修飾的成員變量的生命周期和整個應(yīng)用程序的生命周期一致
2卖毁、例如static修飾Activity的Context特纤,該Context的生命周期和應(yīng)用程序的一致铺韧,當(dāng)Activity要銷毀的時候因為Context被靜態(tài)變量的持有而無法回收赤炒,從而出現(xiàn)內(nèi)存泄漏
// 創(chuàng)建單例時吊骤,需傳入一個Context
// 若傳入的是Activity的Context缎岗,此時單例 則持有該Activity的引用
// 由于單例一直持有該Activity的引用(直到整個應(yīng)用生命周期結(jié)束),即使該Activity退出白粉,該Activity的內(nèi)存也不會被回收
// 特別是一些龐大的Activity传泊,此處非常容易導(dǎo)致OOM
public class SingleInstanceClass {
private static SingleInstanceClass instance;
private Context mContext;
private SingleInstanceClass(Context context) {
this.mContext = context; // 傳遞的是Activity的context
}
public static SingleInstanceClass getInstance(Context context) {
if (instance == null) {
instance = new SingleInstanceClass(context);
}
return instance;
}
}
- 解決方法:應(yīng)傳遞Application的Context,而不是Activity的Context
public class SingleInstanceClass {
private static SingleInstanceClass instance;
private Context mContext;
private SingleInstanceClass(Context context) {
this.mContext = context.getApplicationContext(); // 傳遞的是Application 的context
}
public static SingleInstanceClass getInstance(Context context) {
if (instance == null) {
instance = new SingleInstanceClass(context);
}
return instance;
}
}
<a name="sPnIX"></a>
(2)例子
- MainActivity跳轉(zhuǎn)SecondActivity鸭巴,SecondActivity被單例靜態(tài)持有
- 反復(fù)進入退出SecondActivity 3次后眷细,主動GC(默認不一定及時)
- 然后查看Heap,發(fā)現(xiàn)SecondActivity無法被回收鹃祖,但只有一個溪椎,單例只持有了第一次進入的SecondActivity,后續(xù)的沒有被持有
public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
SingleInstanceClass.getInstance(this);
}
}