Android内存泄漏就这样产生了

zjwijy 2012-02-01

1.资源对象没关闭造成的内存泄漏

描述:

资源性对象比如(Cursor,File文件等)往往都用了一些缓冲,我们在不使用的时候,应该及时关闭它们,以便它们的缓冲及时回收内存。它们的缓冲不仅存在于java虚拟机内,还存在于java虚拟机外。如果我们仅仅是把它的引用设置为null,而不关闭它们,往往会造成内存泄漏。因为有些资源性对象,比如SQLiteCursor(在析构函数finalize(),如果我们没有关闭它,它自己会调close()关闭),如果我们没有关闭它,系统在回收它时也会关闭它,但是这样的效率太低了。因此对于资源性对象在不使用的时候,应该调用它的close()函数,将其关闭掉,然后才置为null.在我们的程序退出时一定要确保我们的资源性对象已经关闭。

程序中经常会进行查询数据库的操作,但是经常会有使用完毕Cursor后没有关闭的情况。如果我们的查询结果集比较小,对内存的消耗不容易被发现,只有在常时间大量操作的情况下才会复现内存问题,这样就会给以后的测试和问题排查带来困难和风险。
 示例代码:

[java]
  1. Cursor cursor = getContentResolver().query(uri...);  
  2. if (cursor.moveToNext()) {  
  3.   ... ...    
  4. }  
修正示例代码:
[java]
  1. Cursor cursor = null;  
  2. try {  
  3.   cursor = getContentResolver().query(uri...);  
  4.   if (cursor != null &&cursor.moveToNext()) {  
  5.       ... ...    
  6.   }  
  7. finally {  
  8.   if (cursor != null) {  
  9.       try {    
  10.           cursor.close();  
  11.       } catch (Exception e) {  
  12.           //ignore this   
  13.       }  
  14.    }  
  15. }  

2.构造Adapter时,没有使用缓存的convertView

描述:

以构造ListView的BaseAdapter为例,在BaseAdapter中提供了方法:
public View getView(int position, ViewconvertView, ViewGroup parent)
来向ListView提供每一个item所需要的view对象。初始时ListView会从BaseAdapter中根据当前的屏幕布局实例化一定数量的view对象,同时ListView会将这些view对象缓存起来。当向上滚动ListView时,原先位于最上面的list item的view对象会被回收,然后被用来构造新出现的最下面的list item。这个构造过程就是由getView()方法完成的,getView()的第二个形参View convertView就是被缓存起来的list item的view对象(初始化时缓存中没有view对象则convertView是null)。由此可以看出,如果我们不去使用convertView,而是每次都在getView()中重新实例化一个View对象的话,即浪费资源也浪费时间,也会使得内存占用越来越大。ListView回收list item的view对象的过程可以查看:
Android.widget.AbsListView.java --> voidaddScrapView(View scrap) 方法。
示例代码:

[java]
  1. public View getView(int position, ViewconvertView, ViewGroup parent) {  
  2.   View view = new Xxx(...);  
  3.   ... ...  
  4.   return view;  
  5. }  
修正示例代码:
[java]
  1. public View getView(int position, ViewconvertView, ViewGroup parent) {  
  2.   View view = null;  
  3.   if (convertView != null) {  
  4.   view = convertView;  
  5.   populate(view, getItem(position));  
  6.   ...  
  7.   } else {  
  8.   view = new Xxx(...);  
  9.   ...  
  10.   }  
  11.   return view;  
  12. }  

相关推荐

ganyouxianjava / 0评论 2012-05-31