内存泄漏的原因有各种各样,如数据库查询的cursor,io流,TypedArray a使用完后手动调用 a.recycle();等等,下面是我看了一些其他博客进行了一个合集 O(∩_∩)O哈哈~,虽然自己不会写博客,这次只是整理了一下人家的知识,也算是一个复习吧,希望以后能写出自己的原创博客。
常见内存泄漏原因
- 静态变量导致的内存泄漏
public class MainActivity extends Activity{
private static View textView;
@override
protected void onCreate(Bundle saveInstanceState){
super.oncreate(saveInstanceState)
setContentView(R.layout.activity_main);
textView = new TextView(this); //这里textView引用了当前context,而静态变量的生命周期是与当前的Activity的生命周期是不一致的,而TextView又引用了context,所以导致不能被回收
}
}
- 单例模式导致的内存泄漏
public class TestListener {
public TestListener() {
}
private static class SingleTonHolder{
private static final TestListener testListener = new TestListener();
}
public static TestListener getInstance(){
return SingleTonHolder.testListener;
}
private List<OnDataArrivedListener> mOnDataArrivedListeners = new ArrayList<OnDataArrivedListener>();
public synchronized void registerListener(OnDataArrivedListener onDataArrivedListener){
if (!mOnDataArrivedListeners.contains(onDataArrivedListener)) {
mOnDataArrivedListeners.add(onDataArrivedListener);
}
}
public synchronized void removeListener(OnDataArrivedListener onDataArrivedListener){
if (mOnDataArrivedListeners!=null) {
mOnDataArrivedListeners.remove(onDataArrivedListener);
}
}
public interface OnDataArrivedListener{
void onDataArrived(Objects objects);
}
}
//activity实现了OnDataArrivedListener接口
public class ItemListActivity extends AppCompatActivity implements TestListener.OnDataArrivedListener {
/**
* Whether or not the activity is in two-pane mode, i.e. running on a tablet
* device.
*/
private boolean mTwoPane;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_item_list);
//这里进行了注册,而在onDestroy中又没有进行解注册,就会导致内存泄漏
TestListener.getInstance().registerListener(this);
- 属性动画导致的内存泄漏
这里Activity停止时,如果没有停止动画,则会导致动画持有mButton,mButton又持有Acitivity,从而导致Activity不会被回收。
protected void onCreate(Bundle saveInstanceState){
super.oncreate(sabeInstanceState);
mButton = (Button)findviewbyid(R.id.btn);
ObjectAnimator animator = ObjectAnimator.ofFloat(mButton,"rotation",0,360);
animator.setRepeatCount(ValueAnimator.INFINITE);
animator.start();
//animator.cancel();
}
- 内部类导致的内存泄漏
private static TestInnerBad testInnerBad = null; //注意这个地方声明的是静态类,而下面TestInnerBad却是非静态的
//静态类的生命周期是与应用的生命周期一样长的,但是这的TestInnerBad引用了非静态类,会导致内存泄漏
class TestInnerBad{
}
protected void onCreate(Bundle saveInstanceState){
super.oncreate(sabeInstanceState);
setContentView(R.layout.activity_inner_bad);
if(testInnerBad == null){
testInnerBad = new TestInnerBad();
}
}
- 集合对象善于清除
在退出程序之前,将集合里面的东西clear掉,如果是static的更需要注意清除。
private List<String> nameList;
private List<Fragment> list;
@Override
public void onDestroy() {
super.onDestroy();
if (nameList != null){
nameList.clear();
nameList = null;
}
if (list != null){
list.clear();
list = null;
}
}
webView 记得destroy()掉
当我们不再需要使用webView的时候,应该调用它的destory()方法来销毁它,并释放其占用的内存,否则其占用的内存长期也不能回收,从而造成内存泄漏。
解决方案:
为webView开启另外一个进程,通过AIDL与主线程进行通信,webView所在的进程可以根据业务的需要选择合适的时机进行销毁,从而达到内存的完整释放。参考
Android开发艺术探索
性能优化系列–焕然一璐
内存泄漏全解析,从此拒绝ANR,让OOM远离你的身边,跟内存泄漏say byebye