zoukankan      html  css  js  c++  java
  • static关键字所导致的内存泄漏问题

    大家都知道内存泄漏和内存溢出是不一样的,内存泄漏所导致的越来越多的内存得不到回收的失手,最终就有可能导致内存溢出,下面说一下使用staitc属性所导致的内存泄漏的问题。

    在dalvik虚拟机中,static变量所指向的内存引用,如果不把它设置为null,GC是永远不会回收这个对象的,所以就有了以下情况:

    [java] view plain copy
     
    1. public class SecondActivity extends Activity{  
    2.     private Handler mHandler = new Handler(){  
    3.         @Override  
    4.         public void handleMessage(Message msg) {  
    5.             super.handleMessage(msg);  
    6.             SecondActivity.this.finish();  
    7.             this.removeMessages(0);  
    8.         }  
    9.     };  
    10.   
    11.     private static Haha haha;  
    12.     @Override  
    13.     protected void onCreate(Bundle savedInstanceState) {  
    14.         super.onCreate(savedInstanceState);  
    15.         haha = new Haha();  
    16.         mHandler.sendEmptyMessageDelayed(0,2000);  
    17.     }  
    18.   
    19.     class Haha{  
    20.   
    21.     }  
    22. }  

    非静态内部类的静态引用。然后在2秒之后我们要finish掉这个activity,会造成什么问题呢?我们知道,内部类和外部类之间是相互持有引用的,SecondActivity实例持有了haha的引用,但这里haha是用static修饰的,上面说了,虚拟机不会回收haha这个对象,从而导致SecondActivity实例也得不到回收,造成内存溢出。

    这货还在这得不到回收。

    怎么解决这个问题呢,很简单,只要在Activity的onDestroy方法里把haha设为null就行啦

    [java] view plain copy
     
    1. protected void onDestroy() {  
    2.     super.onDestroy();  
    3.     if(haha!=null){  
    4.         haha = null;  
    5.     }  
    6. }  

    那么还有另外一种情况,单例的问题。单例也是用了其static属性,很多单例,往往需要用到context对象,而又是通过传值的方式获得,比如:

    先来一个单例

    [java] view plain copy
     
    1. public class SingleInstanceF {  
    2.     private static SingleInstanceF single;  
    3.     private  Context context;  
    4.   
    5.     private SingleInstanceF(Context context){  
    6.         this.context = context;  
    7.     }  
    8.   
    9.     public static SingleInstanceF getInstance(Context context){  
    10.         if(single==null){  
    11.             single = new SingleInstanceF(context);  
    12.         }  
    13.         return single;  
    14.     }  
    15.   
    16. }  

    再来一个Activity来用它,context传入一个this,再2秒之后关闭Activity

    [java] view plain copy
     
    1. public class ThirdActivity extends Activity{  
    2.     private Handler mHandler = new Handler(){  
    3.         @Override  
    4.         public void handleMessage(Message msg) {  
    5.             super.handleMessage(msg);  
    6.             ThirdActivity.this.finish();  
    7.             this.removeMessages(0);  
    8.         }  
    9.     };  
    10.     @Override  
    11.     protected void onCreate(Bundle savedInstanceState) {  
    12.         super.onCreate(savedInstanceState);  
    13.         SingleInstanceF instanceF = SingleInstanceF.getInstance(this);  
    14.         mHandler.sendEmptyMessageDelayed(0,2000);  
    15.     }  
    16. }  

    后来我们发现这货还在,又是得不到回收:

    怎么办呢,还是像上面那样,把静态对象设置为null,或者我们传入context的时候,别传this了,this可是当前Acitvity啊,传Application Context即可。但是不是都可以传Application Context呢,明显不是,有的事是Application Context干不了的,这个得看具体情况而定。

  • 相关阅读:
    对之前IoT项目的完善
    利用 esp8266 搭建简单物联网项目
    IOT(esp8266)
    ---分割线---
    百度云下载工具--雷鸟下载
    Win10安装Ubuntu子系统
    安装Ubuntu虚拟机
    搭建微信公众号后台(二)
    手把手教你基于CentOS8搭建微信订阅号后台服务(一)
    如何在PHP5中通过PDO连接SQLite3数据库
  • 原文地址:https://www.cnblogs.com/huangwentian/p/6926919.html
Copyright © 2011-2022 走看看