Java內(nèi)存泄露的理解與解決__第1頁
Java內(nèi)存泄露的理解與解決__第2頁
Java內(nèi)存泄露的理解與解決__第3頁
Java內(nèi)存泄露的理解與解決__第4頁
免費(fèi)預(yù)覽已結(jié)束,剩余1頁可下載查看

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、Java內(nèi)存泄露的理解與解決_ Java內(nèi)存管理機(jī)制 在C+ 語言中,假如需要?jiǎng)討B(tài)安排一塊內(nèi)存,程序員需要負(fù)責(zé)這塊內(nèi)存的整個(gè)生命周期。從申請安排、到用法、再到最終的釋放。這樣的過程特別敏捷,但是卻非常繁瑣,程序員很簡單由于疏忽而遺忘釋放內(nèi)存,從而導(dǎo)致內(nèi)存的泄露。 Java 語言對內(nèi)存管理做了自己的優(yōu)化,這就是垃圾回收機(jī)制。 Java 的幾乎全部內(nèi)存對象都是在堆內(nèi)存上安排(基本數(shù)據(jù)類型除外),然后由 GC ( garbage collection)負(fù)責(zé)自動(dòng)回收不再用法的內(nèi)存。 上面是Java 內(nèi)存管理機(jī)制的基本狀況。但是假如僅僅理解到這里,我們在實(shí)際的項(xiàng)目開發(fā)中仍舊會(huì)遇到內(nèi)存泄漏的問題?;蛟S有人

2、表示懷疑,既然 Java 的垃圾回收機(jī)制能夠自動(dòng)的回收內(nèi)存,怎么還會(huì)消失內(nèi)存泄漏的狀況呢?這個(gè)問題,我們需要知道 GC 在什么時(shí)候回收內(nèi)存對象,什么樣的內(nèi)存對象會(huì)被 GC 認(rèn)為是“不再用法”的。 Java中對內(nèi)存對象的訪問,用法的是引用的方式。在 Java 代碼中我們維護(hù)一個(gè)內(nèi)存對象的引用變量,通過這個(gè)引用變量的值,我們可以訪問到對應(yīng)的內(nèi)存地址中的內(nèi)存對象空間。在 Java 程序中,這個(gè)引用變量本身既可以存放堆內(nèi)存中,又可以放在代碼棧的內(nèi)存中(與基本數(shù)據(jù)類型相同)。 GC 線程會(huì)從代碼棧中的引用變量開頭跟蹤,從而判定哪些內(nèi)存是正在用法的。假如 GC 線程通過這種方式,無法跟蹤到某一塊堆內(nèi)存,那

3、么 GC 就認(rèn)為這塊內(nèi)存將不再用法了(由于代碼中已經(jīng)無法訪問這塊內(nèi)存了)。 通過這種有向圖的內(nèi)存管理方式,當(dāng)一個(gè)內(nèi)存對象失去了全部的引用之后,GC 就可以將其回收。反過來說,假如這個(gè)對象還存在引用,那么它將不會(huì)被 GC 回收,哪怕是 Java 虛擬機(jī)拋出 OutOfMemoryError 。 Java內(nèi)存泄露 一般來說內(nèi)存泄漏有兩種狀況。一種狀況如在C/C+ 語言中的,在堆中的安排的內(nèi)存,在沒有將其釋放掉的時(shí)候,就將全部能訪問這塊內(nèi)存的方式都刪掉(如指針重新賦值);另一種狀況則是在內(nèi)存對象明明已經(jīng)不需要的時(shí)候,還仍舊保留著這塊內(nèi)存和它的訪問方式(引用)。第一種狀況,在 Java 中已經(jīng)由于垃圾

4、回收機(jī)制的引入,得到了很好的解決。所以, Java 中的內(nèi)存泄漏,主要指的是其次種狀況。 可能光說概念太抽象了,大家可以看一下這樣的例子: Vector v = new Vector( 10 ); for ( int i = 1 ;i 100 ; i + ) Object o = new Object(); v.add(o); o = null ; 在這個(gè)例子中,代碼棧中存在Vector 對象的引用 v 和 Object 對象的引用 o 。在 For 循環(huán)中,我們不斷的生成新的對象,然后將其添加到 Vector 對象中,之后將 o 引用置空。問題是當(dāng) o 引用被置空后,假如發(fā)生 GC ,我們創(chuàng)

5、建的 Object 對象是否能夠被 GC 回收呢?答案是否定的。由于, GC 在跟蹤代碼棧中的引用時(shí),會(huì)發(fā)覺 v 引用,而連續(xù)往下跟蹤,就會(huì)發(fā)覺 v 引用指向的內(nèi)存空間中又存在指向 Object 對象的引用。也就是說盡管 o 引用已經(jīng)被置空,但是 Object 對象仍舊存在其他的引用,是可以被訪問到的,所以 GC 無法將其釋放掉。假如在此循環(huán)之后, Object 對象對程序已經(jīng)沒有任何作用,那么我們就認(rèn)為此 Java 程序發(fā)生了內(nèi)存泄漏。 盡管對于C/C+ 中的內(nèi)存泄露狀況來說, Java 內(nèi)存泄露導(dǎo)致的破壞性小,除了少數(shù)狀況會(huì)消失程序崩潰的狀況外,大多數(shù)狀況下程序仍舊能正常運(yùn)行。但是,在移動(dòng)

6、設(shè)備對于內(nèi)存和 CPU都有較嚴(yán)格的限制的狀況下, Java 的內(nèi)存溢出會(huì)導(dǎo)致程序效率低下、占用大量不需要的內(nèi)存等問題。這將導(dǎo)致整個(gè)機(jī)器性能變差,嚴(yán)峻的也會(huì)引起拋出 OutOfMemoryError ,導(dǎo)致程序崩潰。 一般狀況下內(nèi)存泄漏的避開 在不涉及簡單數(shù)據(jù)結(jié)構(gòu)的一般狀況下,Java 的內(nèi)存泄露表現(xiàn)為一個(gè)內(nèi)存對象的生命周期超出了程序需要它的時(shí)間長度。我們有時(shí)也將其稱為“對象游離”。 例如: public class FileSearch private byte content; private File mFile; public FileSearch(File file) mFile =

7、file; public boolean hasString(String str) int size = getFileSize(mFile); content = new byte size; loadFile(mFile, content); String s = new String(content); return s.contains(str); 在這段代碼中,F(xiàn)ileSearch 類中有一個(gè)函數(shù) hasString ,用來推斷文檔中是否含有指定的字符串。流程是先將mFile 加載到內(nèi)存中,然后進(jìn)行推斷。但是,這里的問題是,將 content 聲明為了實(shí)例變量,而不是本地變量。于是

8、,在此函數(shù)返回之后,內(nèi)存中仍舊存在整個(gè)文件的數(shù)據(jù)。而很明顯,這些數(shù)據(jù)我們后續(xù)是不再需要的,這就造成了內(nèi)存的無故鋪張。 要避開這種狀況下的內(nèi)存泄露,要求我們以C/C+ 的內(nèi)存管理思維來管理自己安排的內(nèi)存。第一,是在聲明對象引用之前,明確內(nèi)存對象的有效作用域。在一個(gè)函數(shù)內(nèi)有效的內(nèi)存對象,應(yīng)當(dāng)聲明為 local 變量,與類實(shí)例生命周期相同的要聲明為實(shí)例變量以此類推。其次,在內(nèi)存對象不再需要時(shí),記得手動(dòng)將其引用置空。 簡單數(shù)據(jù)結(jié)構(gòu)中的內(nèi)存泄露問題 在實(shí)際的項(xiàng)目中,我們常常用到一些較為簡單的數(shù)據(jù)結(jié)構(gòu)用于緩存程序運(yùn)行過程中需要的數(shù)據(jù)信息。有時(shí),由于數(shù)據(jù)結(jié)構(gòu)過于簡單,或者我們存在一些特別的需求(例如,在內(nèi)存允許的狀況下,盡可能多的緩存信息來提高程序的運(yùn)行速度等狀況),我們很難對數(shù)據(jù)結(jié)構(gòu)中數(shù)據(jù)的生命周期作出明確的界定。這個(gè)時(shí)候,我們可以用法Java 中一種特別的機(jī)制來達(dá)到防止內(nèi)存泄露的目的。 之前我們介紹過,Java 的 GC 機(jī)制是建立在跟蹤內(nèi)存的引用機(jī)制上的。而在此之前

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論