性能优化--内存泄漏
什么是内存泄漏?
内存不在GC掌控之内了。当一个对象已经不需要在使用了,本该被回收时,而有另外一个正在使用的对象持有它的引用从而就导致对象不能被回收。这种导致了本该被回收的对象不能被回收而停留在堆内存中,就产生了内存泄漏
内存分配的几种策略
1、静态的
静态的存储区:内存在程序编译的时候就已经分配好,,这块的内存在程序整个运行期间都一直存在。
它主要存放静态数据、全局的static数据和一些常量。
2、栈式的
在执行函数(方法)时,函数一些内部变量的存储都可以放在栈上面创建,函数执行结束的时候这些存储单元就会自动被释放掉。
栈内存包括分配的运算速度很快,因为内置在处理器的里面的。当然容量有限。
3、堆式的
也叫做动态内存分配。有时候可以用malloc或者new来申请分配一个内存。在C/C++可能需要自己负责释放(java里面直接依赖GC机制)。
内存泄露经常出现的例子
1、静态变量引起的内存泄漏
当调用getInstance时,如果传入的context是Activity的context。只要这个单例没有被释放,那这个activity也不会被释放,一直到进程退出才会释放
public class CommUtil {
private static CommUtil instance;
private Context context;
private CommUtil(Context context){
this.context = context;
}
public static CommUtil getInstance(Context mcontext){
if(instance == null){
instance = new CommUtil(mcontext);
}
// else{
// instance.setContext(mcontext);
// }
return instance;
}
2、非静态内部类引起内存泄漏(包括匿名内部类)
错误的示范:
public void loadData(){//隐士持有MainActivity实例。MainActivity.this.a
new Thread(new Runnable() {
@Override
public void run() {
while(true){
try {
//int b=a;
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
3、不需要用的监听未移除会发生内存泄露
4.资源未关闭引起的内存泄露情况
比如:BroadCastReceiver、Cursor、Bitmap、IO流、自定义属性attribute
attr.recycle()回收。
当不需要使用的时候,要记得及时释放资源。否则就会内存泄露。
5.无限循环动画
没有在onDestroy中停止动画,否则Activity就会变成泄露对象。
比如:轮播图效果。