美文网首页
android-内存溢出

android-内存溢出

作者: 舌尖上的Android | 来源:发表于2018-03-01 10:36 被阅读0次

    android中常见内存溢出原因:
    1.数据库的cursor没有关闭。
    2.adapter没有缓存/复用contentview
    3.调用registerReceiver后没有unregisterReceiver;
    4.没有关闭inputstream/outputstream。
    5.Bitmap使用后没有调用recycle();
    6.Context泄漏
    7.读取bitmap对象过大
    8.static关键字等。

    直接引起内存泄漏:

    public class ClassName {  
        private static Context mContext;  
        //省略  
    }   
    // 如果mContext 被赋值,那么对应的context对象无法被释放,将引起内存泄漏。内存泄漏严重的时候会导致oom
    

    间接引起内存泄漏:

     private static Drawable sBackground;   
    
      @Override  
      protected void onCreate(Bundle state) {  
        super.onCreate(state);   
    
        TextView label = new TextView(this);  
        label.setText("Leaks are bad");   
    
        if (sBackground == null) {  
          sBackground = getDrawable(R.drawable.large_bitmap);  
        }  
        label.setBackgroundDrawable(sBackground);   
    
        setContentView(label);  
      }   
    /*虽然并没有显式的保存context的引用,但是drawable与view连接之后,drawable将view设置为一个回调,而view持有context对引用,所以引链如下:
      Drawable->TextView->Context
    所以context同样无法释放,最终引起内存泄漏。
    */
    

    内部类持有外部对象引起内存泄漏:

    public class BasicActivity extends Activity {  
         @Override  
         public void onCreate(Bundle savedInstanceState) {  
             super.onCreate(savedInstanceState);  
             setContentView(R.layout.main);  
             new MyThread().start();  
         }   
    
         private class OneThread extends Thread{  
             @Override  
             public void run() {  
                 super.run();  
                 //do somthing  
             }  
         }  
      }   
    

    由于OneThread 持有外部对象,所以在run函数没有结束时,OneThread不会被销毁,同样外部对象也不会被销毁,因此就出现了内存泄漏的问题。
    而AsyncTask的情况会更严重,因为它内部维持了一个线程池,那么AsyncTask产生的thread的声明周期是不稳定的,因此如果AsyncTask作为acitvity的内部类,就更容易出现内存泄漏的问题,所以一般不建议将AsyncTask作为内部类使用。

    如何解决:将内部类改为静态内部类,并且内部类中使用弱引用保存Context引用。

    bitmap内存泄露解决方法:
    及时回收
    设置采样率,没有必要全部展示的截取一部分展示
    选取合适的分辨率,对图片进行压缩
    巧用软引用,防止内存泄漏

    其他:
    及时关闭InputStream/OutputStream
    及时关闭cursor
    用registerReceiver()后生命周期结束时调用unregisterReceiver()

    相关文章

      网友评论

          本文标题:android-内存溢出

          本文链接:https://www.haomeiwen.com/subject/lrqgxftx.html