1、静态变量
类中定义了静态Activity变量,把当前的Activity赋值给静态变量,如果Activity生命周期结束的时候静态变量没有清空,就会导致内存泄漏。static变量是贯穿整个应用的生命周期,所以被泄漏的Activity就会一直存在于应用的进程中,不会被回收。
private static Activity sActivity;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
sActivity = this;
findViewById(R.id.btn_back).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
});
}
}
2、非静态内部类创建静态实例
这里的非静态内部类是Config,创建的静态实例是sConfig
造成内存泄漏的原因是内部类会隐式持有外部类的引用,这里的外部类是NonStaticActivity,然而内部类sConfig又是static静态变量,其生命周期和Application生命周期一样,所以在NonStaticActivity关闭的时候,内部类实例依然持有对NonStaticActivity的引用,导致NonStaticActivity无法被回收释放,引发内存泄漏。
public class NonStaticActivity extends AppCompatActivity {
private static Config sConfig;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_non_static);
//Config类并不是静态类,
sConfig = new Config();
}
class Config {
}
}
3、匿名内部类导致内存泄露
比方说Thread、Handler等
1、new 出一个匿名的 Thread,进行耗时的操作,如果 MainActivity 被销毁而 Thread 中的耗时操作没有结束的话,便会产生内存泄露;
解决方法:继承 Thread 实现静态内部类
2、new 出一个匿名的 Handler,这时如果 MainActivity 被销毁,而 Handler 里面的消息还没发送完毕的话,Activity 的内存也不会被回收;
解决方法:
A:继承 Handler 实现静态内部类,以及在 Activity 的 onDestroy() 方法中,移除所有的消息 mHandler.removeCallbacksAndMessages(null);
ublic class MainActivity extends AppCompatActivity {
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
。。。。。。
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new Runnable() {
@Override
public void run() {
。。。。。。
}
}).start();
Message message = Message.obtain();
mHandler.sendMessageDelayed(message, 10000);
}
B:通过内部静态类和弱引用的方法来及时释放Activity,需要注意的是在Activity退出时记得清除掉消息队列中的消息
public class MainActivity extends AppCompatActivity {
private MyHandler mHandler = new MyHandler(this);
private TextView mTextView ;
private static class MyHandler extends Handler {
private WeakReference<Context> reference;
public MyHandler(Context context) {
reference = new WeakReference<>(context);
}
@Override
public void handleMessage(Message msg) {
MainActivity activity = (MainActivity) reference.get();
if(activity != null){
activity.mTextView.setText("");
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
mHandler.removeCallbacksAndMessages(null);
}
}
4、单例造成的内存泄露
单例模式是非常常用的设计模式,使用单例模式的类,只会产生一个对象,这个对象看起来像是一直占用着内存,但这并不意味着就是浪费了内存,内存本来就是拿来装东西的,只要这个对象一直都被高效的利用就不能叫做泄露。
实质是静态变量引用Activity,在getInstance(Context context)方法中传入的参数context如果是某个Activity,但是Activity的生命周期较短,而单例作为Static对象是全生命周期的,这样当Activity结束后,单例对象仍然持有Activity的引用,GC机制无法判定为垃圾进行回收,此时发生内存泄露。
public class SingleInstanceTest {
private static SingleInstanceTest sInstance;
private Context mContext;
private SingleInstanceTest(Context context){
//不能直接使用Activity或者短周期的Context
this.mContext = context.getApplicationContext();
}
public static SingleInstanceTest newInstance(Context context){
if(sInstance == null){
sInstance = new SingleInstanceTest(context);
}
return sInstance;
}
}
来源:CSDN
作者:yihuangol
链接:https://blog.csdn.net/yihuangol/article/details/104399177