欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android避免內(nèi)存溢出(Out of Memory)方法匯總

 更新時(shí)間:2017年01月17日 14:54:50   作者:ZHU_文濤  
這篇文章主要為大家詳細(xì)介紹了Android避免內(nèi)存溢出Out of Memory方法匯總,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

避免內(nèi)存溢出的方法,主要是對(duì)以下三個(gè)方面對(duì)程序進(jìn)行優(yōu)化

內(nèi)存引用

在處理內(nèi)存引用之前,我們先來(lái)復(fù)習(xí)下什么是強(qiáng)引用、軟引用、弱引用、虛引用
強(qiáng)引用:強(qiáng)引用是使用最普遍的引用。如果一個(gè)對(duì)象具有強(qiáng)引用,那垃圾回收器絕不會(huì)回收它。 當(dāng)內(nèi)存空間不足,Java虛擬機(jī)寧愿拋出OutOfMemoryError錯(cuò)誤,使程序異常終止,也不會(huì)靠隨意回收具有強(qiáng)引用的對(duì)象來(lái)解決內(nèi)存不足的問(wèn)題。

軟引用:如果一個(gè)對(duì)象只具有軟引用,但內(nèi)存空間足夠時(shí),垃圾回收器就不會(huì)回收它;直到虛擬機(jī)報(bào)告內(nèi)存不夠時(shí)才會(huì)回收, 只要垃圾回收器沒(méi)有回收它,該對(duì)象就可以被程序使用。軟引用可用來(lái)實(shí)現(xiàn)內(nèi)存敏感的高速緩存。 軟引用可以和一個(gè)引用隊(duì)列(ReferenceQueue)聯(lián)合使用,如果軟引用所引用的對(duì)象被垃圾回收器回收,Java虛擬機(jī)就會(huì)把這個(gè)軟引用加入到與之關(guān)聯(lián)的引用隊(duì)列中。

弱引用:只具有弱引用的對(duì)象擁有更短暫的生命周期。在垃圾回收器線程掃描它所管轄的內(nèi)存區(qū)域的過(guò)程中,一旦發(fā)現(xiàn)了只具有弱引用的對(duì)象,不管當(dāng)前內(nèi)存空間是否足夠,都會(huì)回收它的內(nèi)存。 不過(guò),由于垃圾回收器是一個(gè)優(yōu)先級(jí)很低的線程,因此不一定會(huì)很快發(fā)現(xiàn)那些只具有弱引用的對(duì)象。 弱引用可以和一個(gè)引用隊(duì)列(ReferenceQueue)聯(lián)合使用,如果弱引用所引用的對(duì)象被垃圾回收,Java虛擬機(jī)就會(huì)把這個(gè)弱引用加入到與之關(guān)聯(lián)的引用隊(duì)列中。

虛引用:虛引用可以理解為虛設(shè)的引用,與其他幾種引用都不同,虛引用并不會(huì)決定對(duì)象的生命周期。如果一個(gè)對(duì)象僅持有虛引用,那么它就和沒(méi)有任何引用一樣,在任何時(shí)候都可能被垃圾回收器回收。 虛引用主要用來(lái)跟蹤對(duì)象被垃圾回收器回收的活動(dòng)。 虛引用與軟引用和弱引用的一個(gè)區(qū)別在于:虛引用必須和引用隊(duì)列 (ReferenceQueue)聯(lián)合使用。 當(dāng)垃圾回收器準(zhǔn)備回收一個(gè)對(duì)象時(shí),如果發(fā)現(xiàn)它還有虛引用,就會(huì)在回收對(duì)象的內(nèi)存之前,把這個(gè)虛引用加入到與之 關(guān)聯(lián)的引用隊(duì)列中。 程序可以通過(guò)判斷引用隊(duì)列中是否已經(jīng)加入了虛引用,來(lái)了解被引用的對(duì)象是否將要被垃圾回收。 如果程序發(fā)現(xiàn)某個(gè)虛引用已經(jīng)被加入到引用隊(duì)列,那么就可以在所引用的對(duì)象的內(nèi)存被回收之前采取必要的行動(dòng)。

1、釋放強(qiáng)引用

一般我們?cè)诼暶鲗?duì)象變量時(shí),使用完后就不管了,認(rèn)為垃圾回收器會(huì)幫助我們回收這些對(duì)象所指向的內(nèi)存空間,實(shí)際上如果這個(gè)對(duì)象的內(nèi)存空間還處在被引用狀態(tài)的話,垃圾回收器是永遠(yuǎn)不會(huì)回收它的內(nèi)存空間的,只有當(dāng)這個(gè)內(nèi)存空間不被任何對(duì)象引用的時(shí)候,垃圾回收器才會(huì)去回收。
所以我們?cè)谑褂猛陮?duì)象后,可以把對(duì)象置為空,這樣我的垃圾回收器gc就會(huì)在合適的時(shí)候釋放掉為該對(duì)象分配的內(nèi)存空間

Object obj = new Object(); 
obj = null; 

當(dāng)然,在置為空前要確認(rèn)是否不再需要使用該對(duì)象了,如果需要隨時(shí)使用這個(gè)對(duì)象,則不能這么做

2、使用軟引用

在jvm報(bào)告內(nèi)存不足之前會(huì)清除所有的軟引用,這樣的話gc就可以收集到很多軟引用釋放出來(lái)的內(nèi)存空間,從而解決內(nèi)存吃緊的問(wèn)題,避免內(nèi)存溢出,什么時(shí)候被回收取決于gc的算法和gc運(yùn)行時(shí)可用的內(nèi)存大小。
我們可以用SoftReference來(lái)封裝強(qiáng)引用的對(duì)象

String str = "zhuwentao";  // 強(qiáng)引用 
SoftReference<String> strSoft = new SoftReference<String>(str); 

 // 使用軟引用封裝強(qiáng)引用 

3、使用弱引用
gc收集弱引用對(duì)象的執(zhí)行過(guò)程和軟引用一樣,只是gc不會(huì)根據(jù)內(nèi)存情況來(lái)決定是否回收弱引用的對(duì)象。

String str = "zhuwentao";  // 強(qiáng)引用 
WeakReference<String> strWeak = new WeakReference<String>(str);  

// 使用弱引用封裝強(qiáng)強(qiáng)引用 

如果你希望能夠隨時(shí)取得某個(gè)對(duì)象的信息,但又不希望影響該對(duì)象的垃圾回收,則應(yīng)該使用WeakReference來(lái)記住該對(duì)象,而不是使用一般的Reference。

圖像處理

大部分的OOM都是發(fā)生在圖片加載上的,當(dāng)我們加載大圖時(shí),需要特別注意避免OOM的發(fā)生。
處理大圖片時(shí),不管你的手機(jī)內(nèi)存有多大,如果不對(duì)圖片進(jìn)行處理,都有可能會(huì)發(fā)生內(nèi)存溢出問(wèn)題。
因?yàn)锳ndroid系統(tǒng)會(huì)為每一個(gè)應(yīng)用分配一定大小的內(nèi)存,并不會(huì)把整個(gè)系統(tǒng)內(nèi)存全部分給應(yīng)用,所以不管你手機(jī)內(nèi)存多大,對(duì)每個(gè)App來(lái)說(shuō),它能使用的內(nèi)存都是有限的。
這和PC端是有很大的不同,PC端如果內(nèi)存不夠了還可以請(qǐng)求使用虛擬內(nèi)存,而Android系統(tǒng)可沒(méi)這個(gè)機(jī)制。

1、在內(nèi)存中壓縮圖片

裝載大圖片時(shí)需要對(duì)圖片進(jìn)行壓縮,使用等比例壓縮的方法直接在內(nèi)存中處理圖片

Options options = new BitmapFactory.Options(); 
options.inSampleSize = 5; // 原圖的五分之一,設(shè)置為2則為二分之一 
BitmapFactory.decodeFile(myImage.getAbsolutePath(), options); 

這樣做要注意的是,圖片質(zhì)量會(huì)變差,inSampleSize設(shè)置的值越大,圖片質(zhì)量就越差,不同的手機(jī)廠商縮放的比例可能不同。

2、使用完圖片后回收?qǐng)D片所占內(nèi)存

由于Android外層是使用java而底層使用的是c語(yǔ)言在里層為圖片對(duì)象分配的內(nèi)存空間。
所以我們的外部雖然看起來(lái)釋放了,但里層卻并不一定完全釋放了,我們使用完圖片后最好再釋放掉里層的內(nèi)存空間。

if (!bitmapObject.isRecyled()) {  // Bitmap對(duì)象沒(méi)有被回收 
  bitmapObject.recycle();  // 釋放 
  System.gc();  // 提醒系統(tǒng)及時(shí)回收 
} 

3、降低要顯示的圖片色彩質(zhì)量

Android中Bitmap有四種圖片色彩模式:
ALPHA_8:每個(gè)像素需要占用內(nèi)存中的1byte
RGB_565:每個(gè)像素需要占用內(nèi)存中的2byte
ARGB_4444:每個(gè)像素需要占用內(nèi)存中的2byte
ARGB_8888:每個(gè)像素需要占用內(nèi)存中的4byte
我們創(chuàng)建Bitmap時(shí),默認(rèn)的色彩模式是ARGB_8888的,這種色彩模式是質(zhì)量最高的,當(dāng)然這樣的模式占用的內(nèi)存也最大。
而ARGB_4444每個(gè)像素只占用2byte,所以使用ARGB_4444的模式也能降低圖片占用的內(nèi)存大小。

BitmapFactory.Options options = new BitmapFactory.Options(); 
options.inPreferredConfig = Bitmap.Config.ARGB_4444; 
Bitmap btimapObject = BitmapFactory.decodeFile(myImage.getAbsolutePath(), options); 

其實(shí)大多數(shù)圖片設(shè)置成ARGB_4444模式后,在顯示上是看不出與ARGB_8888模式有什么差別的,只是在具有漸變色效果的圖片時(shí),可能會(huì)讓漸變色呈現(xiàn)色彩條樣的效果。
這種降低色彩質(zhì)量的方法對(duì)內(nèi)存的降低效果不如方法1明顯。

4、查詢圖片信息時(shí)不把圖片加載到內(nèi)存中

有時(shí)候我們?nèi)〉靡粡垐D片,也許只是為了獲得這個(gè)圖片的一些信息,比如圖片的width、height等信息,不需要顯示到界面上,這個(gè)時(shí)候我們可以不把圖片加載到內(nèi)存中。

BitmapFactory.Options options = new BitmapFactory.Options(); 
options.inJustDecodeBounds = true;  // 不把圖片加載到內(nèi)存中 
Bitmap btimapObject = BitmapFactory.decodeFile(myImage.getAbsolutePath(), options); 

inJustDecodeBounds屬性,如果值為true,那么將不返回實(shí)際的Bitmap對(duì)象,也不給其分配內(nèi)存空間,但允許我們查詢圖片寬、高、大小等基本信息。
(獲取原始寬高:options.outWidth,options.outHeight)

VMRuntime

VMRuntime是Android SDK中提供的一個(gè)類。
只在Android2.3以前有用,2.3以后的SDK就不支持了,所以這個(gè)VMRuntime并不通用。
這里簡(jiǎn)單介紹下就好了。

1、優(yōu)化Dalvik虛擬機(jī)的堆內(nèi)存分配

VMRuntime類提供的setTargetHeapUtilization方法可以增強(qiáng)程序堆內(nèi)存的處理效率。

private final static float TARGET_HEAP_UTILIZATION = 0.75f; 
VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION); 

2、自定義堆內(nèi)存大小
強(qiáng)制定義Android給當(dāng)前App分配的內(nèi)存大小,使用VMRuntime設(shè)置應(yīng)用最小堆內(nèi)存。

// 設(shè)置最小heap內(nèi)存為 6MB 大小 
private final static int HEAP_SIZE = 6 * 1024 * 1024 ; 
VMRuntime.getRuntime().setMinimumHeapSize(HEAP_SIZE); 

largeHeap
讓Dalvik虛擬機(jī)為App分配更大的內(nèi)存,該方法能為我們的App爭(zhēng)取到更多內(nèi)存空間,從而緩解內(nèi)存不足的壓力
可以在程序中使用ActivityManager.getMemoryClass()方法來(lái)獲取App內(nèi)存正常使用情況下的大小,通過(guò)ActivityManager.getLargeMemoryClass()可獲得開啟largeHeap時(shí)最大的內(nèi)存大小

1、使用方法

該方法使用非常簡(jiǎn)單,只要在AndroidManifest.xml文件中的<application>節(jié)點(diǎn)屬性中加上”android:largeHeap="true"“

<application 
 android:icon="@mipmap/ic_launcher" 
 android:label="@string/app_name" 
 android:theme="@style/AppTheme" 
 android:largeHeap="true" 

2、注意

Dalvik為我們App增加的內(nèi)存很可能是通過(guò)殺死其它后臺(tái)進(jìn)程獲取的內(nèi)存,這樣的做法對(duì)于一個(gè)開發(fā)者來(lái)說(shuō)并不道義
我們不應(yīng)該把解決OOM的問(wèn)題寄托在爭(zhēng)取最大的內(nèi)存上,應(yīng)該通過(guò)合理的代碼編寫來(lái)盡可能的規(guī)避OOM問(wèn)題。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 自定義Toast工具類ToastUtil防止多次點(diǎn)擊時(shí)Toast不消失的方法

    自定義Toast工具類ToastUtil防止多次點(diǎn)擊時(shí)Toast不消失的方法

    下面小編就為大家?guī)?lái)一篇自定義Toast工具類ToastUtil防止多次點(diǎn)擊時(shí)Toast不消失的方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-04-04
  • Android省電的秘密之JobScheduler

    Android省電的秘密之JobScheduler

    JobScheduler是Android L版本新引入的API,JobScheduler,顧名思義,是用來(lái)調(diào)度工作。工作被調(diào)度的條件包括網(wǎng)絡(luò)變化,充電插拔,周期執(zhí)行等。谷歌為什么要引入這個(gè)新的API呢?是為了省電而制定的一種規(guī)范。下面跟著小編一起來(lái)看下吧
    2017-02-02
  • Android開發(fā)X Y軸Board的繪制教程示例

    Android開發(fā)X Y軸Board的繪制教程示例

    這篇文章主要為大家介紹了Android開發(fā)X Y軸Board的繪制教程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • Android手機(jī)衛(wèi)士之設(shè)置密碼對(duì)話框

    Android手機(jī)衛(wèi)士之設(shè)置密碼對(duì)話框

    這篇文章主要為大家詳細(xì)介紹了Android手機(jī)衛(wèi)士之設(shè)置密碼對(duì)話框,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • Android組合式自定義控件實(shí)現(xiàn)購(gòu)物車加減商品操作

    Android組合式自定義控件實(shí)現(xiàn)購(gòu)物車加減商品操作

    這篇文章主要介紹了Android組合式自定義控件實(shí)現(xiàn)購(gòu)物車加減商品操作,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • Android NTP 時(shí)間同步機(jī)制詳解

    Android NTP 時(shí)間同步機(jī)制詳解

    這篇文章主要為大家介紹了Android NTP時(shí)間同步機(jī)制實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • Android開發(fā)使用Drawable繪制圓角與圓形圖案功能示例

    Android開發(fā)使用Drawable繪制圓角與圓形圖案功能示例

    這篇文章主要介紹了Android開發(fā)使用Drawable繪制圓角與圓形圖案功能,結(jié)合具體實(shí)例形式分析了Drawable繪制圓角矩形的實(shí)現(xiàn)步驟與使用方法,需要的朋友可以參考下
    2017-10-10
  • Android用ActionBar高仿微信主界面的實(shí)例代碼

    Android用ActionBar高仿微信主界面的實(shí)例代碼

    這篇文章主要介紹了Android用ActionBar高仿微信主界面的實(shí)例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-05-05
  • Android 國(guó)際貨幣格式化的示例代碼

    Android 國(guó)際貨幣格式化的示例代碼

    本篇文章主要介紹了Android 國(guó)際貨幣格式化的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-11-11
  • Android懸浮窗的實(shí)現(xiàn)步驟

    Android懸浮窗的實(shí)現(xiàn)步驟

    最近想做一個(gè)懸浮窗秒表的功能,所以看下懸浮窗具體的實(shí)現(xiàn)步驟,接下來(lái)通過(guò)本文給大家介紹Android懸浮窗的實(shí)現(xiàn),需要的朋友可以參考下
    2024-01-01

最新評(píng)論