一般来说,java虚拟机是可以自动gc的,因此对于一些刚入门的android开发者来说,很难意识到android开发中会有内存泄露的情况发生。
在这里简单总结一下android中可能发生内存泄露的几种情形。
<strong>一、数据库使用后没有关闭游标</strong>
数据库使用之后一定要记得cursor.close(),否则在大量、长时间的使用之后,会造成严重后果,而这种问题很难排查。
例如:
ContentResolver contentResolver = this.getContentResorlver(uri,null,null,null,null);
Cursor cursor = contentResolver.query();
if(cursor.moveToNext()){
}
这里的写法是有问题的,最好写为:
Cursor cursor = null;
cursor = this.getResolver(uri,null,null,null,null);
try{
if(cursor!=null&&cursor.moveToNext()){
}
}catch{
}finally{
if(cursor!=null){
try{
cursor.close();
}catch{
}
}
}
二、bitmap对象回收图片占用的内存
bitmap.recycle();回收图片内存。注意对于常用的图片可以不必回收,缓存。但是对于确定不用的或者可能不太常用的图片,尽量回收它的资源。
三、java代码不规范
例如最常见的
Object obj = null;
List<Object> list = new ArrayList<Object>();
for(int i=10;i>0;i--){
obj = = new Object;
list.add(obj);
}
obj = null
虽然最后obj也被置为null,但是由于list中还是有10个Object的引用,所以这些对象资源依然没有被释放。
当然并不是说这种写法错误,因为在后续中根据需求可能会用到list中的Object。但是如果用不到这些,或者用完了后list没有置为null,那么这些对象就泄露了。
同时对于常见的handler,也会有内存泄露。例如在activity中new一个Handler对象,通常是使用
Handler handler - new Handler(){
public void handmessage(Message msg){
......
}
}
Runnable r = new Runnable(){
public void run(){
//下载等耗时操作
handler.sendMessage(....);
}
};
Thread t = new Thread(r);
t.start();
当用户的下载工作还没完成,但是用户退出当前的anctivity时,由于内部类handler拥有外部activity的引用,而线程拥有handler的引用,因此下载没结束,线程没结束,handler没结束,activity也就没接收,内存泄露。
解决方式时将handler定义为static,这样他就只与类相关,与对象无关。同时也要引用弱引用,时handler可以使用外部类activity的对象:
static class MyHandler extends Handler{
WeakReference<Activity> wr = null;
public MyHandler(Activtiy activity){
wr = new WeakReference<Activity>(activity);
}
public void sendMessage(){
final Activity activity = wr.get();
if(activity!=null){
............
}
}
四、adapter中使用converview
其他再补充。
我也是新手