Android之內(nèi)存管理及優(yōu)化-干貨

一、Android內(nèi)存基礎(chǔ)##

  1. 物理內(nèi)存與進(jìn)程內(nèi)存
    物理內(nèi)存即移動設(shè)備上的RAM悦屏,當(dāng)啟動一個Android程序時节沦,會啟動一個Dalvik VM進(jìn)程,系統(tǒng)會給它分配固定的內(nèi)存空間(16M,32M不定)础爬,這塊內(nèi)存空間會映射到RAM上某個區(qū)域甫贯。然后這個Android程序就會運行在這塊空間上。Java里會將這塊空間分成Stack棧內(nèi)存Heap堆內(nèi)存看蚜。stack里存放對象的引用叫搁,heap里存放實際對象數(shù)據(jù)。
    在程序運行中會創(chuàng)建對象供炎,如果未合理管理內(nèi)存渴逻,比如不及時回收無效空間就會造成內(nèi)存泄露,嚴(yán)重的話可能導(dǎo)致使用內(nèi)存超過系統(tǒng)分配內(nèi)存音诫,即內(nèi)存溢出OOM惨奕,導(dǎo)致程序卡頓甚至直接退出。

  2. 內(nèi)存泄露(Memory Leak)
    Java內(nèi)存泄漏指的是進(jìn)程中某些對象(垃圾對象)已經(jīng)沒有使用價值了竭钝,但是它們卻可以直接或間接地引用到gc roots導(dǎo)致無法被GC回收梨撞。Dalvik VM具備的GC機(jī)制(垃圾回收機(jī)制)會在內(nèi)存占用過多時自動回收,嚴(yán)重時會造成內(nèi)存溢出OOM香罐。

  3. 內(nèi)存溢出OOM
    當(dāng)應(yīng)用程序申請的java heap空間超過Dalvik VM HeapGrowthLimit時卧波,溢出。
    注意:OOM并不代表內(nèi)存不足穴吹,只要申請的heap超過Dalvik VM HeapGrowthLimit時幽勒,即使內(nèi)存充足也會溢出。效果是能讓較多進(jìn)程常駐內(nèi)存港令。

  4. 如果RAM不足時系統(tǒng)會做什么啥容?
    Android的Memory Killer會殺死優(yōu)先級較低的進(jìn)程,讓高優(yōu)先級進(jìn)程獲取更多內(nèi)存顷霹。

  5. Android系統(tǒng)默認(rèn)內(nèi)存回收機(jī)制

  • 進(jìn)程優(yōu)先級Foreground進(jìn)程咪惠、Visible進(jìn)程、Service進(jìn)程淋淀、Background進(jìn)程遥昧、Empty進(jìn)程;

如果用戶按Home鍵返回桌面,那么該app成為Background進(jìn)程朵纷;如果按Back返回炭臭,則成為Empty進(jìn)程

  • ActivityManagerService直接管理所有進(jìn)程的內(nèi)存資源分配。所有進(jìn)程要申請或釋放內(nèi)存都需要通過ActivityManagerService對象袍辞。
  • 垃圾回收不定期執(zhí)行鞋仍。當(dāng)內(nèi)存不夠時就會遍歷heap空間,把垃圾對象刪除搅吁。
  • 堆內(nèi)存越大威创,則GC的時間更長
回收未被引用對象

二、優(yōu)化##

  1. Bitmap優(yōu)化
    Bitmap非常消耗內(nèi)存谎懦,而且在Android中肚豺,讀取bitmap時, 一般分配給虛擬機(jī)的圖片堆棧只有8M界拦,所以經(jīng)常造成OOM問題吸申。所以有必要針對Bitmap的使用作出優(yōu)化:
  • 圖片顯示:加載合適尺寸的圖片,比如顯示縮略圖的地方不要加載大圖享甸。
  • 圖片回收:使用完bitmap截碴,及時使用Bitmap.recycle()回收。

問題:Android不是自身具備垃圾回收機(jī)制嗎枪萄?此處為何要手動回收隐岛。
Bitmap對象不是new生成的,而是通過BitmapFactory生產(chǎn)的瓷翻。而且通過源碼可發(fā)現(xiàn)是通過調(diào)用JNI生成Bitmap對象nativeDecodeStream()等方法)聚凹。所以,加載bitmap到內(nèi)存里包括兩部分齐帚,Dalvik內(nèi)存Linux kernel內(nèi)存妒牙。前者會被虛擬機(jī)自動回收。而后者必須通過recycle()方法对妄,內(nèi)部調(diào)用nativeRecycle()讓linux kernel回收湘今。

  • 捕獲OOM異常:程序中設(shè)定如果發(fā)生OOM的應(yīng)急處理方式。
  • 圖片緩存:內(nèi)存緩存剪菱、硬盤緩存
  • 圖片壓縮:直接使用ImageView顯示Bitmap時會占很多資源摩瞎,尤其當(dāng)圖片較大時容易發(fā)生OOM拴签。可以使用BitMapFactory.Options對圖片進(jìn)行壓縮旗们。
  • 圖片像素:android默認(rèn)顏色模式為ARGB_8888蚓哩,顯示質(zhì)量最高,占用內(nèi)存最大上渴。若要求不高時可采用RGB_565等模式岸梨。圖片大小:圖片長度*寬度*單位像素所占據(jù)字節(jié)數(shù)
    ARGB_4444:每個像素占用2byte內(nèi)存
    ARGB_8888:每個像素占用4byte內(nèi)存 (默認(rèn))
    RGB_565:每個像素占用2byte內(nèi)存
  1. 對象引用類型
  • 強(qiáng)引用 strongObject object=new Object()稠氮。當(dāng)內(nèi)存不足時曹阔,Java虛擬機(jī)寧愿拋出OOM內(nèi)存溢出異常,也不會輕易回收強(qiáng)引用對象來解決內(nèi)存不足問題隔披;
  • 軟引用 soft:只有當(dāng)內(nèi)存達(dá)到某個閾值時才會去回收赃份,常用于緩存
  • 弱引用 weak :只要被GC線程掃描到了就進(jìn)行回收锹锰;
  • 虛引用
    如果想要避免OOM發(fā)生芥炭,則使用軟引用對象,即當(dāng)內(nèi)存快不足時進(jìn)行回收恃慧;如果想盡快回收某些占用內(nèi)存較大的對象园蝠,例如bitmap,可以使用弱引用痢士,能被快速回收彪薛。不過如果要對bitmap作緩存就不要使用弱引用,因為很快就會被GC回收怠蹂,導(dǎo)致緩存失敗善延。

關(guān)于java對象引用類型,具體可參加本人另一篇文章

  1. 池 pool
  • 對象池:如果某個對象在創(chuàng)建時城侧,需要較大的資源開銷易遣,那么可以將其放入對象池,即將對象保存起來嫌佑,下次需要時直接取出使用豆茫,而不用再次創(chuàng)建對象。當(dāng)然屋摇,維護(hù)對象池也需要一定開銷揩魂,故要衡量。
  • 線程池:與對象池差不多炮温,將線程對象放在池中供反復(fù)使用火脉,減少反復(fù)創(chuàng)建線程的開銷。
  1. 緩存

關(guān)于android緩存機(jī)制,具體可參加本人另一篇文章

參考文章:

Android性能倦挂、內(nèi)存優(yōu)化
Android操作系統(tǒng)的內(nèi)存回收機(jī)制-IBM
Bitmap內(nèi)存優(yōu)化
內(nèi)存優(yōu)化合集

Android技術(shù)·面試技巧·職業(yè)感悟
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末畸颅,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子妒峦,更是在濱河造成了極大的恐慌重斑,老刑警劉巖兵睛,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肯骇,死亡現(xiàn)場離奇詭異,居然都是意外死亡祖很,警方通過查閱死者的電腦和手機(jī)笛丙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來假颇,“玉大人胚鸯,你說我怎么就攤上這事”考Γ” “怎么了姜钳?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長形耗。 經(jīng)常有香客問我哥桥,道長,這世上最難降的妖魔是什么激涤? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任拟糕,我火速辦了婚禮,結(jié)果婚禮上倦踢,老公的妹妹穿的比我還像新娘送滞。我一直安慰自己,他們只是感情好辱挥,可當(dāng)我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布犁嗅。 她就那樣靜靜地躺著,像睡著了一般晤碘。 火紅的嫁衣襯著肌膚如雪褂微。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天哼蛆,我揣著相機(jī)與錄音蕊梧,去河邊找鬼。 笑死腮介,一個胖子當(dāng)著我的面吹牛肥矢,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼甘改,長吁一口氣:“原來是場噩夢啊……” “哼旅东!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起十艾,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤抵代,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后忘嫉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體荤牍,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年庆冕,在試婚紗的時候發(fā)現(xiàn)自己被綠了康吵。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡访递,死狀恐怖晦嵌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情拷姿,我是刑警寧澤惭载,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站响巢,受9級特大地震影響描滔,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜抵乓,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一伴挚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧灾炭,春花似錦茎芋、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至铡原,卻和暖如春偷厦,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背燕刻。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工只泼, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人卵洗。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓请唱,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子十绑,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內(nèi)容