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干不了的,這個得看具體情況而定。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM