Android--慎用static靜態變數
Android是用Java開發,其靜態變數的生命週期遵守Java的設計。靜態變數是在類被load的時候分配記憶體的,並且存在於方法區。當類被解除安裝的時候,靜態變數被銷燬。在PC機的客戶端程式中,一個類被載入和解除安裝,可簡單的等同於jvm程序的啟動和結束。那麼在Android中呢?用的Dalvik vm也是一樣的。不過Android不太突出的程序概念,所以對靜態變數的生命週期就會感覺模糊,這種模糊對於值型別是無所謂的,如果是靜態的物件引用,則與記憶體回收、記憶體洩漏這些問題有關,有必要加深研究和理解。
一、靜態變數在類被載入的時候分配記憶體。
類在什麼時候被載入?
當我們啟動一個app的時候,系統會建立一個程序,此程序會載入一個Dalvik VM的例項,然後程式碼就執行在DVM之上,類的載入和解除安裝,垃圾回收等事情都由DVM負責。也就是說在程序啟動的時候,類被載入,靜態變數被分配記憶體。
二、靜態變數在類被解除安裝的時候銷燬。
類在什麼時候被解除安裝?
在程序結束的時候。
說明:一般情況下,所有的類都是預設的ClassLoader載入的,只要ClassLoader存在,類就不會被解除安裝,而預設的ClassLoader生命週期是與程序一致的,本文討論一般情況。
三、Android中的程序什麼時候結束
這個是Android對程序和記憶體管理不同於PC的核心——如果資源足夠,Android不會殺掉任何程序,另一個意思就是程序隨時可能會被殺掉。而Android會在資源夠的時候,重啟被殺掉的程序。也就是說靜態變數的值,如果不做處理,是不可靠的,可以說記憶體中的一切都不可靠。如果要可靠,還是得儲存到Nand或SD卡中去,在重啟的時候恢復回來。
另一種情況就是不能把退出所有Activity等同於程序的退出,所以在使用者點選圖示啟動應用的時候,以前存放於靜態變數中的值,有可能還存在,因此要視具體情況給予清空操作。
四、Application也是一樣不可靠
Application其實是一個單例物件,也是放在記憶體中的,當程序被殺掉,就全清空了,只不過Android系統會幫重建Application,而我們存放在Application的資料自然就沒有了,還是得自己處理。
五、靜態引用的物件不會被垃圾回收
只要靜態變數沒有被銷燬也沒有置null,其物件一直被保持引用,也即引用計數不可能是0,因此不會被垃圾回收。因此,單例物件在執行時不會被回收。