转自:http://www.linuxidc.com/Linux/2011-10/44785.htm

因为Android使用Java作为开发语言,很多人在使用会不注意内存的问题。

于是有时遇到程序运行时不断消耗内存,最终导致OutOfMemery,程序异常退出,这就是内存泄露导致的。

我们现在就来总结一下可能导致内存泄露的情况:

  1. 查询数据库而没有关闭Cursor

    在Android中,Cursor是很常用的一个对象,但在写代码是,经常会有人忘记调用close, 或者因为代码逻辑问题状况导致close未被调用。


    通常,在Activity中,我们可以调用startManagingCursor或直接使用managedQuery让Activity自动管理Cursor对象。
    但需要注意的是,当Activity介绍后,Cursor将不再可用!
    若操作Cursor的代码和UI不同步(如后台线程),那没需要先判断Activity是否已经结束,或者在调用OnDestroy前,先等待后台线程结束。

    除此之外,以下也是比较常见的Cursor不会被关闭的情况:

    1. try{
    2. Cursorc=queryCursor();
    3. inta=c.getInt(1);
    4. ......
    5. c.close();
    6. }catch(Exceptione){
    7. }
    虽然表面看起来,Cursor.close()已经被调用,但若出现异常,将会跳过close(),从而导致内存泄露。

    所以,我们的代码应该以如下的方式编写:

    1. Cursorc=queryCursor();
    2. try{
    3. inta=c.getInt(1);
    4. ......
    5. }catch(Exceptione){
    6. }finally{
    7. c.close();//在finally中调用close(),保证其一定会被调用
    8. }

  2. 调用registerReceiver后未调用unregisterReceiver().

    在调用registerReceiver后,若未调用unregisterReceiver,其所占的内存是相当大的。
    而我们经常可以看到类似于如下的代码:

    1. registerReceiver(newBroadcastReceiver(){
    2. ...
    3. },filter);...
    这是个很严重的错误,因为它会导致BroadcastReceiver不会被unregister而导致内存泄露。


  3. 未关闭InputStream/OutputStream

    在使用文件或者访问网络资源时,使用了InputStream/OutputStream也会导致内存泄露


  4. Bitmap使用后未调用recycle()

    根据SDK的描述,调用recycle并不是必须的。但在实际使用时,Bitmap占用的内存是很大的,所以当我们不再使用时,尽量调用recycle()以释放资源。


  5. Context泄露

    这是一个很隐晦的内存泄露的情况。
    先让我们看一下以下代码:
    1. privatestaticDrawablesBackground;
    2. @Override
    3. protectedvoidonCreate(Bundlestate){
    4. super.onCreate(state);
    5. TextViewlabel=newTextView(this);
    6. label.setText("Leaksarebad");
    7. if(sBackground==null){
    8. sBackground=getDrawable(R.drawable.large_bitmap);
    9. }
    10. label.setBackgroundDrawable(sBackground);
    11. setContentView(label);
    12. }

    在这段代码中,我们使用了一个static的Drawable对象。
    这通常发生在我们需要经常调用一个Drawable,而其加载又比较耗时,不希望每次加载Activity都去创建这个Drawable的情况。
    此时,使用static无疑是最快的代码编写方式,但是其也非常的糟糕。
    当一个Drawable被附加到View时,这个View会被设置为这个Drawable的callback (通过调用Drawable.setCallback()实现)。
    这就意味着,这个Drawable拥有一个TextView的引用,而TextView又拥有一个Activity的引用。
    这就会导致Activity在销毁后,内存不会被释放。

更多相关文章

  1. Android内存泄漏终极解决篇(上)
  2. Android studio中Git的学习和使用心得(二)在Android studio中如何
  3. Android Studio代码调试大全
  4. Android 实现闪屏页和右上角的倒计时跳转实例代码
  5. android语音识别方法示例代码
  6. Linux 3.3内核发布 融合Android源代码
  7. Android中的内存使用状况统计

随机推荐

  1. android EditText控件
  2. android 判断应用程序是否已安装
  3. 49 Android(安卓)fragment 自定义适配器a
  4. Android自动弹出软键盘
  5. android 异步下载图片
  6. android窃密短信监听
  7. Android中获取指定日期是星期几
  8. android 对话框中的进度条 (ProgressDial
  9. Android文件操作
  10. Android(安卓)- 购物车页面【仿】淘宝App