丝袜人妻一区二区三区_少妇福利无码视频_亚洲理论片在线观看_一级毛片国产A级片

當(dāng)前位置:首頁 > 攻略

【cfoutofmemory怎么解決】Android應(yīng)用OOM問題分析及解決方案

1.什么是OOM?

03-21 21:05:28 . 771: e/dalvikvm-heap(13316): out of memory on a 10485776-byte allocation .

03-21 21:05:28.7793360 e/Android運(yùn)行時(13316): Java . lang . out of memory error

這幾句話的意思是,我們的程序申請需要10485776byte太大,虛擬機(jī)無法滿足我們,可恥的shutdown自殺了。這種現(xiàn)象通常出現(xiàn)在使用大量圖片或大圖片的APP開發(fā)中。一般來說,當(dāng)APP需要申請一塊內(nèi)存來安裝照片時,系統(tǒng)認(rèn)為APP已經(jīng)使用了足夠的內(nèi)存。(大衛(wèi)亞設(shè),Northern Exposure(美國電視新聞),即使有1G的空閑內(nèi)存,我也不同意為APP提供更多內(nèi)存。然后,系統(tǒng)會立即產(chǎn)生OOM錯誤,如果程序沒有捕獲錯誤,炸彈箱就會崩潰。

2.為什么有OOM?

如果請求的內(nèi)存資源超過此限制,則會出現(xiàn)OOM錯誤,因?yàn)锳ndroid系統(tǒng)中的每個app的每個進(jìn)程或每個虛擬機(jī)都有最大內(nèi)存限制。與整個設(shè)備的其馀內(nèi)存沒有太大關(guān)系。例如,以前Android系統(tǒng)的虛擬機(jī)最多有16M的內(nèi)存,當(dāng)app啟動后,虛擬機(jī)將繼續(xù)請求內(nèi)存資源裝載圖片,如果超過內(nèi)存限制,將出現(xiàn)OOM。Android系統(tǒng)的APP內(nèi)存限制是如何確定的?

2.1 Android的APP內(nèi)存組件:

APP內(nèi)存由Java堆dalvik內(nèi)存和本地內(nèi)存兩部分組成。在此處創(chuàng)建的對象將分配給此處,native是通過c/c請求的內(nèi)存。位圖是以這種方式分配的。Android3.0之后的系統(tǒng)默認(rèn)通過dalvik分配,native作為堆進(jìn)行管理。這兩部分加起來不能超過Android對單個進(jìn)程、虛擬機(jī)的內(nèi)存限制。

每個手機(jī)的內(nèi)存限制大小是多少?

activity manager activity manager=(activity manager)

AC();

上述方法返回以M為單位的數(shù)字,每個系統(tǒng)平臺或設(shè)備的值都不同,如HTC基本24M、galaxy 36M、EMULA24M等。我的座右銘xt681是42米。3

以上是虛擬機(jī)的最大內(nèi)存資源。

對于Head堆大小限制,可以查看/system文件。

Dalvik.vm.heapstartsize=5m

Dalvik.vm.heapgrowthlimit=48m

Dalvik.vm.heapsize=256m

注:heapsize參數(shù)表示單個進(jìn)程heap可以使用的最大內(nèi)存,但如果存在以下參數(shù)“dalvik.vm.headgrowthlimit=48m”,則表示單個進(jìn)程heap內(nèi)存限制為48m。換句話說,程序執(zhí)行過程實(shí)際上只能使用48m內(nèi)存。

2.2 Android系統(tǒng)為什么設(shè)置APP的內(nèi)存限制?

1開發(fā)人員內(nèi)存使用應(yīng)更加合理。通過限制每個應(yīng)用程序可用的最大內(nèi)存限制,某些應(yīng)用程序可能會惡意或無意地使用太多內(nèi)存。這導(dǎo)致其他應(yīng)用程序無法正常工作。Android是一個多進(jìn)程,因此,如果一個進(jìn)程(即應(yīng)用程序)使用了太多內(nèi)存,則無法運(yùn)行其他應(yīng)用程序。因?yàn)橛芯窒扌?,開發(fā)人員必須善用有限的資源,優(yōu)化資源使用。

2屏幕顯示內(nèi)容有限,內(nèi)存足夠就可以了。需要使用數(shù)千萬張照片上千萬個數(shù)據(jù),但在特定時間點(diǎn)需要向用戶顯示的東西總是有限的。因?yàn)槠聊伙@示太大,可以放在上面的信息有限。大部分信息都已準(zhǔn)備好顯示,因此不需要給heap內(nèi)存太多。也就是說,出現(xiàn)OOM現(xiàn)象,大多數(shù)原因是我們的程序設(shè)計有問題,需要優(yōu)化。優(yōu)化方法有很多。例如,通過時間改變空間,繼續(xù)加載要使用的照片,繼續(xù)回收不使用的照片,將大照片分析為適合手機(jī)屏幕大小的圖片。

3需要多個APP多個虛擬機(jī)davlik限制。Android的app使用獨(dú)立虛擬機(jī),每次打開應(yīng)用程序時都會打開一個或多個獨(dú)立虛擬機(jī)。這樣可以防止虛擬機(jī)崩潰導(dǎo)致整個系統(tǒng)崩潰,需要浪費(fèi)更多內(nèi)存。這個設(shè)計保證了Android的穩(wěn)定性。

不是2.3 GC自動回收資源嗎?為什么會有OOM?

Android不會使用GC自動回收資源。為什么app的未使用資源不被回收利用?

Android的GC根據(jù)特定算法回收程序未使用的內(nèi)存資源,防止app的內(nèi)存應(yīng)用程序大致堆積,但GC通?;厥盏馁Y源是無主的對象內(nèi)存、軟參考資源或軟參考資源。例如:

Bitmap Bt=bi (this.getresources()、r . drawable . splash);//此時照片資源是強(qiáng)參考,是主人所在的資源。

Bt=null//此時,這幅畫資源是無主的。Gc心情號碼去回收。

softreferencebitmap soft ref=new softreferencebitmap(Bt);

Bt=null

其他代碼……。

當(dāng)程序請求大量內(nèi)存資源時,GC可以釋放softref引用的此圖片內(nèi)存。Bt=(),此時可以

能得到的是null,需要重新加載圖片。

當(dāng)然這也說明了用軟引用圖片資源的好處,就是gc會自動根據(jù)需要釋放資源,一定程度上避免OOM。

TIPS:編程要養(yǎng)成習(xí)慣,不用的對象設(shè)置為null。其實(shí)更好的是,不用的圖片直接recycle。因?yàn)橥ㄟ^設(shè)置null讓gc來回收,有時候還是會來不及。

2.4 怎么查看APP內(nèi)存分配情況?

1 通過DDMS中的heap選項卡監(jiān)視內(nèi)存情況:

Heap視圖中部有一個叫做data object, 即數(shù)據(jù)對象,也就是我們的程序中大量存在的類類型的對象。

在data object一行中有一列是"Total Size", 其值就是當(dāng)前進(jìn)程中所有Java數(shù)據(jù)對象的內(nèi)存總量。如果代碼中存在沒有釋放對象引用的情況,則data object的"Total Size"值在每次gc后不會有美線的回落。隨著操作次數(shù)的增加"Total Size"的值會越來越大。直到到達(dá)一個上限 后導(dǎo)致進(jìn)程被kill掉。

2 在App里面我們可以通過totalMemory與freeMemory:

Run().freeMemory()

RUn().totalMemory()

3 adb shell dumpsys meminfo com.android.demo

3. 常見避免OOM的幾個注意點(diǎn):

3.1 適當(dāng)調(diào)整圖像大小 。因?yàn)槭謾C(jī)屏幕尺寸有限,分配給圖像的顯示區(qū)域有限,尤其對于超大圖片,加載自網(wǎng)絡(luò)或者sd卡,圖片文件提及達(dá)到幾M或者十幾個M的:

加載到內(nèi)存前,先算出該bitmap的大小,然后通過適當(dāng)調(diào)節(jié)采樣率使得加載的圖片剛好,或稍大捷克在手機(jī)屏幕上顯示就滿意了:

Bim opts = new Bi();

o = true ;

o(opts, minSideLength, maxNumOfPixels); // Android 提供了一種動態(tài)計算的方法 computeSampleSize

o = false ;

try {

return Bi(imageFile, opts);

} catch (OutOfMemoryError err){

}

3.2 圖像緩存 。在listview或Gallery等控件中一次性加載大量圖片時,只加載屏幕顯示的資源,尚未顯示的不加載,移出屏幕的資源及時釋放,采用強(qiáng)引用+軟引用2級緩存,提高加載性能。緩存圖像到內(nèi)存,采用軟引用緩存到內(nèi)存,而不是在每次使用的時候都從新加載到內(nèi)存。

3.3 采用低內(nèi)存占用量的編碼方式 。比如Bi比Bi更省內(nèi)存。

3.4 及時回收圖像 。如果引用了大量的Bitmap對象,而應(yīng)用又不需要同時顯示所有圖片??梢詫簳r不用到的Bitmap對象及時回收掉。對于一些明確直到圖片使用情況的場景可以主動recycle回收

App的啟動splash畫面上的圖片資源,使用完就recycle。對于幀動畫,可以加載一張,畫一張,釋放一張。

3.5 不要在循環(huán)中創(chuàng)建過多的本地變量 。慎用static,用static來修飾成員變量時,該變量就屬于該類,而不是該類實(shí)例,它的生命周期是很長的。如果用它來引用一些內(nèi)存占用太多的實(shí)例,這時候就要謹(jǐn)慎對待了。

3.6 自定義堆內(nèi)存分配大小 。優(yōu)化Dalvik虛擬機(jī)的堆內(nèi)存分配。

public class ClassName{

private static Context mContext;

// 省略

}

4. App使用圖片時避免OOM的幾種方式:

4.1 直接null或recycle

對于app里使用的大量圖片,采用方式:使用時加載,不顯示時直接置null或recycle。

這樣處理是個好習(xí)慣,記本可以杜絕OOM,但是缺憾是代碼多了,可能會忘記某些資源recycle。

而有些情況下會出現(xiàn)特定圖片反復(fù)加載,釋放,再加載等,低效率的事情。

4.2 簡單通過SoftReference引用方式管理圖片資源

建個SoftReference的hashmap

使用圖片時先查詢這個hashmap是否有softreference, softreference里的圖片是否為空,

如果為空就加載圖片到softreference并加入hashmap。

無需再代碼里顯式的處理圖片的回收與釋放,gc會自動處理資源的釋放。

這種方式處理起來簡單實(shí)用,能一定程度上避免前一種方法反復(fù)加載釋放的低效率。但還不夠優(yōu)化。

4.3 強(qiáng)引用+軟引用二級緩存

Android示范程序ImageDownloader.java, 使用了一個二級緩存機(jī)制。就是有一個數(shù)據(jù)結(jié)構(gòu)直接持有解碼成功的Bitmap對象引用,同時使用一個二級緩存數(shù)據(jù)結(jié)構(gòu)保持淘汰的Bitmap的softreference對象,由于softreference對象的特殊性,系統(tǒng)會再需要內(nèi)存的時候首先將softreference持有的對象釋放掉,也就是說當(dāng)vm發(fā)現(xiàn)可用的內(nèi)存較少需要出發(fā)gc的時候,二級緩存中的bitmap對象將被回收,而持有一級緩存的bitmap對象用于顯示。

其實(shí)這個解決方案最為關(guān)鍵的一點(diǎn)是使用了一個比較合適的數(shù)據(jù)結(jié)構(gòu),那就是LinkedHashMap類型來進(jìn)行一級緩存Bitmap的容器。由于LinkeHashMap的特殊性,我們可以控制其內(nèi)存存儲對象的個數(shù)并且將不在使用的對象從容器中移除,放到softreference二級緩存里,我們可以在一級緩存中一致保存最近被訪問到的bitmap對象,而已經(jīng)被訪問過的圖片在LinkedHashMap的容量超過我們預(yù)設(shè)值時將會把容器中存在的時間最長的對象移除,這個時候我么可以將被移除的LinkedHashMap中的放到二級緩存容器,而二級緩存中的對象管理就交給系統(tǒng)來做了,當(dāng)系統(tǒng)需要gc時就會首先回收二級緩存容器的Bitmap對象了。

在獲取圖片對象時候先從一級緩存容器中查找,如果有對應(yīng)對象并可用直接返回,如果沒有的話從二級緩存中查找對應(yīng)的SoftReference, 判斷SoftReference對象持有的Bitmap是否可用,可用直接返回,否則返回空。如果二級緩存都找不到圖片,那就直接加載圖片資源。

4, LruCache + sd的緩存方式

5. 兩種容易OOM的場景建議:

5.1 網(wǎng)絡(luò)下載大量圖片

比如微博客戶端: 多線程異步網(wǎng)絡(luò),小兔直接用LRUCache+SoftRef+Sd,大圖按需下載:

5.2 對于需要加載非常多條目信息的listview,gridview等的情況

在adapter的getView函數(shù)里有個convertView參數(shù),告知你是否有可重用的view對象。 如果不使用convertView的話,每次調(diào)用getView時每次都會重新創(chuàng)建view,這樣之前的view可能還沒銷毀,加之不斷的新建view勢必會造成內(nèi)存劇增,從而導(dǎo)致OOM。另外在重用convertView時,里面原有的圖片等資源就會變成無主的了。

這里Google官方推薦使用:"convertview+靜態(tài)類viewholder"

官方給出解釋是:

a 重用緩存convertView傳遞給getView()方法來避免填充不必要的視圖。

b 使用ViewHolder模式來避免沒有必要的調(diào)用findViewById;因?yàn)樘嗟膄indViewById也會影響性能。

附ViewHolder類的作用:ViewHolder模式通過在getView方法返回的視圖的標(biāo)簽(tag)中存儲一個數(shù)據(jù)結(jié)構(gòu)。這個數(shù)據(jù)結(jié)構(gòu)包含了指向我們要綁定數(shù)據(jù)的視圖的引用,從而避免每次調(diào)用getView()的時候調(diào)用findViewById();

6 申請超過內(nèi)存限制的內(nèi)存分配方式:

6.1 從Native C分配內(nèi)存。使用NDK(本地開發(fā)工具包)和JNI, 它可能從C級(如malloc/free或新建/刪除)分配內(nèi)存,這樣的分配是不計入24MB的限制。這是真的,從本機(jī)代碼分配內(nèi)存是為了java方便,但它可以被用來存儲在ram的數(shù)據(jù)(即使圖片數(shù)據(jù))的一些打擊呢。

6.2 使用OpenGL的紋理。紋理內(nèi)存不計入限制,要查看你的應(yīng)用程序確實(shí)分配了多少內(nèi)存可以使用android.os.Debug.getNativeHeapAllocatedSize(), 可以使用上面介紹的兩種技術(shù)的Nexus之一,我可以輕松地為一個單一的前臺進(jìn)程分配300MB-10倍以上的默認(rèn)24MB 的限制,從上面看來使用native代碼分配內(nèi)存是不在24MB的限制內(nèi)的(開放的GL的質(zhì)地也是使用native代碼分配內(nèi)存)。

但是,這兩個方法的風(fēng)險就是,本地堆分配內(nèi)存超過系統(tǒng)可用內(nèi)存限制的話,通常都是直接崩潰。

1.《【cfoutofmemory怎么解決】Android應(yīng)用OOM問題分析及解決方案》援引自互聯(lián)網(wǎng),旨在傳遞更多網(wǎng)絡(luò)信息知識,僅代表作者本人觀點(diǎn),與本網(wǎng)站無關(guān),侵刪請聯(lián)系頁腳下方聯(lián)系方式。

2.《【cfoutofmemory怎么解決】Android應(yīng)用OOM問題分析及解決方案》僅供讀者參考,本網(wǎng)站未對該內(nèi)容進(jìn)行證實(shí),對其原創(chuàng)性、真實(shí)性、完整性、及時性不作任何保證。

3.文章轉(zhuǎn)載時請保留本站內(nèi)容來源地址,http://f99ss.com/gl/2561848.html

上一篇

【非誠勿擾首輪全滅】不要給吳工商添麻煩,竟然有24盞燈全滅了!

下一篇

【we對ig】LPL大會回顧iG和WE的老對手宿命戰(zhàn)WE2-0戰(zhàn)勝IG。

【cfoutofmemory怎么解決】Win10系統(tǒng)CF中出現(xiàn)out  of  memory解決步驟!

【cfoutofmemory怎么解決】Win10系統(tǒng)CF中出現(xiàn)out of memory解決步驟!

cfoutofmemory怎么解決相關(guān)介紹,[PConline信息] Win10系統(tǒng)CF出現(xiàn)outofmemory怎么辦?很多用戶在玩CF時會出現(xiàn)outofmemory的系統(tǒng)提示,出現(xiàn)這種情況的原因有很多。下一篇在Win10系統(tǒng)CF中列出了ou...

【cfoutofmemory怎么解決】6399:死亡細(xì)胞埋在骨頭里的out  of  memory如何解決?

【cfoutofmemory怎么解決】6399:死亡細(xì)胞埋在骨頭里的out of memory如何解決?

cfoutofmemory怎么解決相關(guān)介紹,6399:埋葬死亡細(xì)胞的奧圖奧莫里如何解決?很多玩家在《死亡細(xì)胞》賣場結(jié)束時暴露了奧圖奧莫里的bug,不知道是怎么回事。如何解決這個bug?從下一篇6399篇開始,我將分享死亡細(xì)胞。 死亡細(xì)胞掩埋ou...

【cfoutofmemory怎么解決】CF歷屆游戲路線圖你從哪個時代開始的?

【cfoutofmemory怎么解決】CF歷屆游戲路線圖你從哪個時代開始的?

cfoutofmemory怎么解決相關(guān)介紹,還記得當(dāng)時拿著P90的吳某嗎?貼吧一位老玩家精心整理了穿越火線歷屆游戲的加載界面截圖。后面沒有更新,但看到這些畫,小小的編制熱淚盈眶。充滿回憶! 這次給大家?guī)淼氖荂F歷代裝載圖。希望大家喜歡。 有些...