概念
虛擬機(jī)垃圾回收
談到內(nèi)存一定少不了java虛擬機(jī)的垃圾回收策略感局,java語言不再像C/C++那樣需要人工手動分配內(nèi)存和釋放內(nèi)存宣脉,完全由虛擬機(jī)的垃圾回收進(jìn)程來釋放不用的內(nèi)存徐块,垃圾回收進(jìn)程是一個優(yōu)先級很低的進(jìn)程吠撮,當(dāng)一個對象在內(nèi)存中不可達(dá)時博脑,就會被認(rèn)為是無用的內(nèi)存饲嗽,垃圾回收器就會在某個不確定的時間對其進(jìn)行釋放驻谆。關(guān)于java的垃圾回收策略可參考這篇文章--http://blog.csdn.net/u012152619/article/details/46981643
永久保存區(qū)域 --- Permanent Generation space
該區(qū)域主要保存類的方法和一些靜態(tài)屬性卵凑,當(dāng)class第一次被load到虛擬機(jī)時庆聘,會將類的一些方法說明和靜態(tài)屬性保存到該區(qū)域,這塊區(qū)域上的數(shù)據(jù)將持續(xù)到應(yīng)用的整個生命周期勺卢,該區(qū)域不受垃圾回收策略影響
棧 --- Stacks
java中伙判,為每個線程分配自己的獨(dú)立棧,棧內(nèi)存是一塊存儲基本數(shù)據(jù)變量和對象引用的區(qū)域黑忱,其數(shù)據(jù)遵從后進(jìn)先出的原則宴抚,棧數(shù)據(jù)回收的方式是根據(jù)其作用域來回收的,比如甫煞,在某個方法內(nèi)菇曲,定義了一個指向某一對象的局部引用,改引用就創(chuàng)建在棧上抚吠,當(dāng)這段方法代碼執(zhí)行完成后常潮,其棧上的引用就會被回收,同時也順應(yīng)了先進(jìn)后出的規(guī)則
堆 --- Heap space
java堆內(nèi)存是存對象實(shí)例和數(shù)組的區(qū)域楷力,這塊內(nèi)存上的數(shù)據(jù)是由垃圾回收器進(jìn)行垃圾回收喊式,垃圾回收線程是一個優(yōu)先級很低的線程柳击,所以當(dāng)棧上指向某一對象實(shí)例的引用被清除后坞生,并不能保證堆上的這個實(shí)例占用的內(nèi)存會被馬上回收掉;
當(dāng)創(chuàng)建數(shù)組的時候椭符,會把數(shù)組的首地址賦到棧上去剪勿,作為引用來操作這個數(shù)組
以上堆受虛擬機(jī)的垃圾回收管理贸诚,永久保存區(qū)域則不會
內(nèi)存問題
內(nèi)存溢出
系統(tǒng)分配給每個應(yīng)用的內(nèi)存都是一定的,當(dāng)應(yīng)用使用的內(nèi)存超過系統(tǒng)分配的內(nèi)存時就會出現(xiàn)內(nèi)存溢出厕吉,如常見OutOfMemeoryException
為了防止內(nèi)存溢出酱固,我們需要及時回收應(yīng)用無用的對象實(shí)例,或者為我們的應(yīng)用申請更大的內(nèi)存空間
內(nèi)存泄露
當(dāng)內(nèi)存中有一塊內(nèi)存我們無法釋放也無法重現(xiàn)分配時头朱,這塊區(qū)域就屬于內(nèi)存泄露了
java已經(jīng)有垃圾回收了运悲,那他還會出現(xiàn)內(nèi)存泄露嗎?
………………………………
………………………………
………………………………
答案是肯定的项钮,人無完人班眯,更何況語言;
一般來說java的內(nèi)存泄露都是這個原因引起的:
對象都是有生命周期的烁巫,有的長署隘,有的短,如果長生命周期的對象持有短生命周期的引用亚隙,就很可能會出現(xiàn)內(nèi)存泄露
常見兩個對象互相引用的問題磁餐,aa類實(shí)例里有一塊數(shù)據(jù),bb類的實(shí)例有一份指向aa類實(shí)例那塊數(shù)據(jù)引用阿弃,bb使用了沒有對引用null诊霹,而aa類也置為null了羞延,這個時候aa類實(shí)例因?yàn)閿?shù)據(jù)被別人引用,所以就不能被釋放脾还,造成內(nèi)存泄露伴箩;
還有一種內(nèi)存泄露,開啟一個存活很久的線程鄙漏,加載一個類嗤谚,在這個類里面創(chuàng)建一個static引用,讓這個引用指向一個new很大的數(shù)組泥张,并把這個static引用賦值到threadLocal變里去呵恢;按照上面的操作重復(fù)操作,就會造成threadlocal
android設(shè)備上的內(nèi)存優(yōu)化
android移動設(shè)備上媚创,內(nèi)存資源本就有限渗钉,合理利用內(nèi)存資源對app的體驗(yàn)是很重要的,主要分為兩大類使用內(nèi)存上和及時銷毀釋放不需要的對象實(shí)例占用內(nèi)存
常見的內(nèi)存優(yōu)化要點(diǎn):
- 數(shù)據(jù)結(jié)構(gòu)的優(yōu)化钞钙,hashmap替換成sparsearray鳄橘,以及Arraymap
- 圖片色彩格式選擇
ALPHA_8:每個像素占用1byte內(nèi)存。
ARGB_4444:每個像素占用2byte內(nèi)存
ARGB_8888:每個像素占用4byte內(nèi)存
RGB_565:每個像素占用2byte內(nèi)存 - Bitmap使用完后記得要recyle
- Cursor記得要close
- Enums類型是static constant內(nèi)存開銷的兩倍
- 單例的慎用
- 生命周期長對象實(shí)例慎用
內(nèi)存泄露資源參考貼:
http://geek.csdn.net/news/detail/127226