赞
踩
是指程序中动态分配的堆内存由于某种原因没有及时回收,造成系统内存的浪费,导致程序运行变慢甚至是崩溃的结果。
根本原因:
一个生命周期较长的对象,强引用持有了一个生命周期较短的对象,导致短生命周期的对象在应该被销毁的时候没有被销毁。
项目中经常会用到一堆的工具类,有些工具类基本上就是全局单例的模式,而且它们在使用的时候又会经常的需要用到Context这个上下文变量,当传入这个变量的时候,这些工具类就会持有对应Activity的强引用了。
public class SingleInstance { //像这样的单例工具类,调用的时候都是直接使用instance变量 //要更新的时候就会调用newInstance private static SingleInstance instance; private Context mContext; private SingleInstance(Context context){ mContext = context; } private static SingleInstance getInstance(Context context){ if (instance == null) return new SingleInstance(context); return instance; } }
public class MainActivity extends AppCompatActivity {
private static MainActivity instance;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
instance = this;
}
}
这种情况下Activity退出后,由于这些单例还持有Activity的强引用,所以导致分配给Activity的堆内存就没法回收,这就造成了内存泄漏。
避免办法:
public class SingleInstance { //像这样的单例工具类,调用的时候都是直接使用instance变量 //要更新的时候就会调用newInstance private static SingleInstance instance; private Context mContext; private SingleInstance(){} private fun(Context context) { // 处理逻辑 } private static SingleInstance getInstance(){ if (instance == null) return new SingleInstance(); return instance; } }
```java
public class MainActivity extends AppCompatActivity {
private static WeakReference<MainActivity> instance;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
instance = new WeakReference<>(this);
}
}
在Java中,非静态内部类会隐形持有外部类的引用,而且是强引用。
有时候经常会需要临时new一个Thread出来工作的情况,这种时候这个临时工线程就会拥有Activity的引用了,这种情况下如果Activity退出销毁后,也不会回收内存,这就又造成内存泄漏了。
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); new Thread(new Runnable() { @Override public void run() { try { //假装在做耗时的工作 Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); } }
还有Handler的内部类使用,我们经常也是这么用的,这个就更夸张了,Android Studio就直接报警告提醒你会内存泄漏了。
Handler的生存周期并不会因为你是写在Activity里面就和Activity一样,所以会造成内存泄漏。
这个也是会不经意间就直接写成Activity内部类的类型,也会持有Activity的强引用。
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); new MyasyncTask().execute(); } static class MyAscnyTask extends AsyncTask<Void, Void, Void>{ @Override protected Void doInBackground(Void... params) { try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } return null; } }
避免办法:
在开发过程中经常会有用到集合的时候,集合内的元素会随着添加而越来越多,如果是静态集合那么生命周期会和应用程序一样长,这样就非常占内存。
static List<Object> objectList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
Object obj = new Object();
objectList.add(obj);
obj = null;
}
避免办法:用不到的集合元素要及时的清理。
静态变量本身的生命周期就和应用程序一样长,不当的使用自然会造成内存泄漏。
避免办法:正确的使用静态变量…之前说的集合那些就避免用静态变量就行了,不得不用的时候就记得清理。
在开发过程中,经常会有应该及时关闭/释放的对象却没有记得这么做,这里就列举一下有哪些
Android 关于内存泄露,你必须了解的东西 - 简书
https://www.jianshu.com/p/65f914e6a2f8
一篇技术好文之Android性能优化内存泄漏无处可藏(图文) - 简书
https://www.jianshu.com/p/86a6d5cd3b05
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。