淺談Android中關于靜態(tài)變量(static)的使用問題
項目中,在不停地接收串口數(shù)據(jù)很長一段時間(幾小時)后,會偶然性的報錯。初步排除了oom和cpu緊張問題,因為是工業(yè)平板不方便調試,用了些比較笨的方法最后鎖定在幾個用了static的地方。在這里記錄下Android中使用static的一些問題。
靜態(tài)變量的生命周期遵守Java的設計。靜態(tài)變量在類被load的時候分配內存,并存在于方法區(qū)。當類被卸載時,靜態(tài)變量被銷毀。在PC機的客戶端程序中,一個類被加載和卸載,可簡單的等同于jvm進程的啟動和結束。在Android中,用的DVM也是一樣的,不過Android中不太突出進程的概念,所以對靜態(tài)變量的生命周期就是感覺模糊,這種模糊對于值類型是無所謂的,如果是靜態(tài)的對象引用,則與內存回收、內存泄露這些問題有關,有必要加深研究和理解。
一、靜態(tài)變量在類被加載的時候分配內存。
類在什么時候被加載?
當我們啟動一個app的時候,系統(tǒng)會創(chuàng)建一個進程,此進程會加載一個DVM實例,然后代碼就運行在DVM之上,類的加載和卸載、垃圾回收等事情都由DVM負責。也就是說進程啟動的時候,類被加載,靜態(tài)變量被分配內存。
二、靜態(tài)變量在類被卸載的時候銷毀。
類在什么時候被卸載?
在進程結束的時候。
說明:一般情況下,所有的類都是默認的ClassLoader加載的,只要ClassLoader存在,類就不會被卸載,而默認的ClassLoader生命周期是與進程一致的,這里討論一般情況。
三、Android的進程什么時候結束
這個是Android對進程和內存管理不同于PC的核心---如果資源足夠,Android不會殺掉任何進程,另一個意思是進程隨時可能會被殺掉。而Android會在資源足夠的時候,重啟被殺掉的進程。也就是說靜態(tài)變量的值,如果不做處理,是不可靠的,可以說內存中的一切都不可靠,如果要可靠,還是保存到Nand或SD卡中去,在重啟的時候恢復回來。
另一個種情況就是不能把退出所有Activity等同于進程的退出,所以在用戶點擊圖標啟動應用的時候,以前存放于靜態(tài)變量中的值,有可能還存在,因此要視具體情況給予清空操作。
四、Application也是一樣不可靠
Application其實是一個單例對象,也是放在內存中的,當進程被殺掉,就全清空了,只不過Android系統(tǒng)會幫重建Application,而我們存放在Application的數(shù)據(jù)自然就沒有了,還是得自己處理。
五、靜態(tài)引用的對象不會被回收?
在除了Android之外的Java運行環(huán)境中,你只要關心進程生命周期,在進程生命周期內你可以放心地使用靜態(tài)變量來保持數(shù)據(jù)。只要靜態(tài)變量沒有被銷毀也沒有置null,其對象一直被保持引用,因此不會被垃圾回收。因此單例對象在運行時不會被回收。但是Android里它隨時會被系統(tǒng)置NULL。
總結:
Android中,我們不知道何時進程會被kill,所有:
1.不能保證靜態(tài)變量會一直存在。(進程可能被Kill掉)
2.每次打開app時靜態(tài)變量的值都是初始值(進程沒有被kill掉所有靜態(tài)變量保存的還是上次的值)。
而靜態(tài)變量是不會被垃圾回收的,其對象一直保持引用,以ARC不可能是0。
以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持腳本之家!
相關文章
android使用SwipeRefreshLayout實現(xiàn)ListView下拉刷新上拉加載
這篇文章主要為大家詳細介紹了android使用SwipeRefreshLayout實現(xiàn)ListView下拉刷新上拉加載,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-12-12
關于Android HTML5 audio autoplay無效問題的解決方案
這篇文章主要介紹了關于Android HTML5 audio autoplay無效問題的解決方案,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-09-09
Android使用自定義控件HorizontalScrollView打造史上最簡單的側滑菜單
側滑菜單一般都會自定義ViewGroup,然后隱藏菜單欄,當手指滑動時,通過Scroller或者不斷的改變leftMargin等實現(xiàn);多少都有點復雜,完成以后還需要對滑動沖突等進行處理,今天給大家?guī)硪粋€簡單的實現(xiàn),史上最簡單有點夸張,但是的確是我目前遇到過的最簡單的一種實現(xiàn)2016-02-02
ViewPager+Fragment實現(xiàn)側滑導航欄
這篇文章主要為大家詳細介紹了ViewPager+Fragment實現(xiàn)側滑導航欄,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-05-05
Android自定義View onDraw()方法會調用兩次的問題解決
這篇文章主要介紹了Android自定義View onDraw()方法會調用兩次的問題解決,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧2024-01-01
Android帶清除功能的輸入框控件EditTextWithDel
這篇文章主要為大家詳細介紹了Android帶清除功能的輸入框控件EditTextWithDel,感興趣的小伙伴們可以參考一下2016-09-09
Android中使用IntentService創(chuàng)建后臺服務實例
這篇文章主要介紹了Android中使用IntentService創(chuàng)建后臺服務實例,IntentService提供了在單個后臺線程運行操作的簡單結構,需要的朋友可以參考下2014-06-06
android圖像繪制(七)ClipRect局部繪圖/切割原圖繪制總結
這幾天開始學游戲地圖制作,今天小小的總結一下Canvas的clipRect()接口的使用,接下來介紹ClipRect局部繪圖/切割原圖繪制感興趣的朋友可以了解下2013-01-01

