转自: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(安卓)Wifi模块分析(三)
  2. Android中dispatchDraw分析
  3. Android四大基本组件介绍与生命周期
  4. Android(安卓)Service AIDL
  5. Android调用天气预报的WebService简单例子
  6. android打电话发短信
  7. android 拨打紧急号码,通话时开启免提功能实现
  8. Android调用.NET Webservice报org.ksoap2.serialization.SoapPri
  9. android 自定义view

随机推荐

  1. golang ide有哪些
  2. golang读取文本乱码解决方法
  3. golang http怎么使用
  4. erlang和golang的区别
  5. go语言网络编程、http处理流程详情
  6. golang gopath如何设置
  7. docker为什么用golang开发
  8. Go安装各种第三方库、包的命令
  9. golang gin可以做什么
  10. go语言函数介绍