要優(yōu)化內(nèi)存际歼,先要弄懂a(chǎn)ndroid內(nèi)存體系说莫。
計(jì)算器:這是線程私有的, 標(biāo)記線程執(zhí)行到哪兒了。不會(huì)拋出異常
虛擬機(jī)棧:線程私有赢赊,棧幀用來(lái)存放局部變量表 操作數(shù)棧 方法出口等乙漓。
局部變量表存放了編譯器已知的基本數(shù)據(jù)類型, 對(duì)象引用
本地方法棧:主要是native方法執(zhí)行需要用到的棧
方法區(qū):類信息、常量域携、靜態(tài)變量簇秒,運(yùn)行時(shí)常量池
運(yùn)行時(shí)常量池記錄了編譯器的各種字面量和符號(hào)引用。
堆: Java堆是被所有線程共享的一塊內(nèi)存區(qū)域秀鞭,在虛擬機(jī)啟動(dòng)時(shí)創(chuàng)建趋观,是虛擬機(jī)所管理的內(nèi)存中最大的一塊。此內(nèi)存區(qū)域的唯一目的就是【存放對(duì)象實(shí)例和數(shù)組】锋边,幾乎所有的對(duì)象實(shí)例和數(shù)組都在這里分配內(nèi)存皱坛。
棧內(nèi)存的回收:
棧也會(huì)內(nèi)存溢出的,例如你寫個(gè)遞歸豆巨。java棧內(nèi)存的內(nèi)存回收就是利用方法和棧的特性來(lái)做的剩辟。
基礎(chǔ)類型變量?jī)H方法內(nèi)的局部變量保存在棧內(nèi)存中,成員變量保存在堆中往扔。
堆內(nèi)存的回收:
Java的垃圾回收機(jī)制GC贩猎,GC僅運(yùn)行在堆內(nèi)存上,開始學(xué)習(xí)GC之前你應(yīng)該知道一個(gè)詞:stop-the-world萍膛。
GC有多種回收算法吭服,但不管哪種回收算法,在GC回收時(shí)除了gc所需要的線程外蝗罗,其他線程都會(huì)掛起直到GC結(jié)束艇棕,GC調(diào)優(yōu)通常就是為了改善stop-the-wrold的時(shí)間。
Android Dalvik Heap與原生Java一樣串塑,將堆的內(nèi)存空間分為三個(gè)區(qū)域沼琉,
Young Generation,Old Generation桩匪, Permanent Generation打瘪。
- 最近分配的對(duì)象會(huì)存放在Young Generation區(qū)域,當(dāng)這個(gè)對(duì)象經(jīng)過數(shù)次GC后依然存活,它會(huì)被移動(dòng)到Old Generation闺骚,最后累積一定時(shí)間再移動(dòng)到Permanent Generation區(qū)域桃移。系統(tǒng)會(huì)根據(jù)內(nèi)存中不同的內(nèi)存數(shù)據(jù)類型分別執(zhí)行不同的gc操作。
- 圖中的permanent generation稱為方法區(qū)葛碧,其中存儲(chǔ)著類和接口的元信息以及interned的字符串信息借杰。所以這一區(qū)域并不是為老年代中存活下來(lái)的對(duì)象所定義的持久區(qū)。方法區(qū)中也會(huì)發(fā)生GC进泼,這里的GC同樣也被稱為major GC蔗衡。
很多手機(jī)廠商號(hào)稱的無(wú)卡頓安卓,無(wú)非就是利用一些比較成熟的基于統(tǒng)計(jì)乳绕,機(jī)器學(xué)習(xí)的算法定時(shí)清理數(shù)據(jù)绞惦,清理內(nèi)存,甚至提前加載數(shù)據(jù)到內(nèi)存洋措。