http://www.reibang.com/p/402225fce4b2
內(nèi)存泄露:
當(dāng)一個對象已經(jīng)不在使用了,本該被回收時恃泪,而有另外一個正在使用的對象持有它的引用,從而導(dǎo)致了對象不能被GC所回收犀斋。這種導(dǎo)致了本該被回收的對象不能被回收而停留在堆內(nèi)存中贝乎,就產(chǎn)生了內(nèi)存泄露。
內(nèi)存溢出:
當(dāng)應(yīng)用的heap資源超出了Dalvik虛擬機(jī)分配的內(nèi)存就會溢出叽粹。
Android為每個進(jìn)程設(shè)置Dalvik Heap Size閾值览效,這個閾值在不同的設(shè)備上會因為RAM大小不同而各有差異。如果APP想要分配的內(nèi)存超過這個閾值球榆,就會發(fā)生OOM朽肥。
ActivityManager.getMemoryClass()可以查詢當(dāng)前APP的Heap Size閾值禁筏,單位是MB持钉。
內(nèi)存泄露帶來的影響:
應(yīng)用卡頓
泄露的內(nèi)存影響了GC的內(nèi)存分配,過多的內(nèi)存泄露會影響應(yīng)用的執(zhí)行效率篱昔。
應(yīng)用異常(OOM)
過多的內(nèi)存泄露每强,最終會導(dǎo)致Dalvik分配的內(nèi)存,出現(xiàn)OOM
JVM內(nèi)存管理
java采用GC進(jìn)行內(nèi)存管理州刽。JVM內(nèi)存分配的幾種策略:
1空执、靜態(tài)的
靜態(tài)的存儲區(qū),內(nèi)存在程序編譯的時候就已經(jīng)分配好了穗椅,這塊內(nèi)存在程序整個運(yùn)行期間都一直存在辨绊,它主要存放靜態(tài)數(shù)據(jù)、全局的static數(shù)據(jù)以及一些常量匹表。
2门坷、棧式的
在執(zhí)行方法時,方法一些內(nèi)部變量的存儲都可以放在棧上面創(chuàng)建袍镀,方法執(zhí)行結(jié)束的時候默蚌,這些存儲單元格就會自動被注釋掉。棧內(nèi)存包括分配的運(yùn)算速度很快苇羡,因為內(nèi)在在處理器里面绸吸。當(dāng)然容量有限,并且棧式一塊連續(xù)的內(nèi)存區(qū)域,大小是由操作系統(tǒng)決定的锦茁,他先進(jìn)后出攘轩,進(jìn)出完成不會產(chǎn)生碎片,運(yùn)行效率高且穩(wěn)定
3码俩、堆式的
也叫動態(tài)內(nèi)存
我們通常使用new來申請分配一個內(nèi)存撑刺。GC會根據(jù)內(nèi)存的使用情況,對堆內(nèi)存里垃圾內(nèi)存進(jìn)行回收握玛。堆內(nèi)存是一塊不連續(xù)的內(nèi)存區(qū)域够傍,如果頻繁的new/remove會造成大量的內(nèi)存碎片,GC頻繁的回收挠铲,導(dǎo)致內(nèi)存抖動冕屯,消耗應(yīng)用性能。
可以使用一些標(biāo)記來讓GC更好的對內(nèi)存進(jìn)行回收:
StrongReference (強(qiáng)引用)
任何時候GC是不能回收他的拂苹,哪怕內(nèi)存不足時安聘,系統(tǒng)會直接拋出異常OutOfMemoryError,也不會去回收 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
進(jìn)程終止
SoftReference (軟引用)當(dāng)內(nèi)存足夠時不會回收這種引用類型的對象瓢棒,只有當(dāng)內(nèi)存不夠用時才會回收
內(nèi)存不足浴韭,進(jìn)行GC的時候
WeakReference (弱引用)GC一運(yùn)行就會把給回收了GC后終止
PhantomReference (虛引用)
如果一個對象與虛引用關(guān)聯(lián),則跟沒有引用與之關(guān)聯(lián)一樣脯宿,在任何時候都可能被垃圾回收器回收
任何時候都有可能