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