版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、【深入java虛擬機(jī)(8)】: java垃圾收集機(jī)制-編程 開發(fā)技術(shù)【深入java虛擬機(jī)(8)】: java垃圾收 集機(jī)制原文出處:蘭亭風(fēng)雨對象引用java中的垃圾回收一般是在java堆中進(jìn)行,因為堆中幾乎存放了 java中所有 的對象實例。談到j(luò)ava堆中的垃圾冋收,自然要談到引用。在jdk1. 2之前,java 小的引用定義很很純粹:如果reference類型的數(shù)據(jù)屮存儲的數(shù)值代表的是另外 一塊內(nèi)存的起始地址,就稱這塊內(nèi)存代表著一個引用。但在jdk1. 2之后,java 對引用的概念進(jìn)行了擴(kuò)充,將其分為強(qiáng)引用(strong?reference)、軟引用(soft?reference)、弱引
2、用(weak?reference)、虛引用(phantom?reference) 四種,引用強(qiáng)度依次減弱。 強(qiáng)引用:如“objcct?obj?二?new?object () ”,這類引用是java程序中最普遍的。只 要強(qiáng)引用還存在,垃圾收集器就永遠(yuǎn)不會回收掉被引用的對彖。軟引用:它用來描述一些可能還有用,但并非必須的對象。在系統(tǒng)內(nèi)存不夠用時, 這類引川關(guān)聯(lián)的對象將被垃圾收集器回收ojdkl.2之后捉供了 softreference類來實 現(xiàn)軟引用。弱引用:它也是用來描述非需對象的,但它的強(qiáng)度比軟引用更弱些,被弱引用關(guān)聯(lián) 的對象只能生存島下一次垃圾收集發(fā)生z前。當(dāng)垃圾收集器工作吋,無論當(dāng)前內(nèi)存
3、是否足夠,都會回收掉只被弱引用關(guān)聯(lián)的對象。在jdk1.2之后,提供了 weakreference類來實現(xiàn)弱引用。虛引用:最弱的一種引用關(guān)系,完全不會對其生存時間構(gòu)成影響,也無法通過虛引 用來取得一個對象實例。為一個對象設(shè)置虛引用關(guān)聯(lián)的唯一 ii的是希望能在這個對 象被收集器回收時收到一個系統(tǒng)通知。jdk1.2 z后提供了 phantomreference類來實 現(xiàn)虛引用。垃圾對象的判定java堆小存放著幾乎所有的對象實例,垃圾收集器對堆小的對彖進(jìn)行回收前, 要先確定這些對象是否還有用,判定對象是否為垃圾對象有如下算法:? ?引用計數(shù)算法 給對象添加一個引用計數(shù)器,每當(dāng)有一個地方引用它時,計數(shù)器
4、值就加1,當(dāng)引 用失效時,計數(shù)器值就減i,任何時刻計數(shù)器都為0的對彖就是不可能再被使用 的。引用計數(shù)算法的實現(xiàn)簡單,判定效率也很高,在人部分情況下它都是一個不錯的 選擇,當(dāng)ja腹語言并沒有選擇這種算法來進(jìn)行垃圾冋收,主要原因是它很難解 決對彖之間的相互循環(huán)引用問題。? ?根搜索算法java和c#小都是采用根搜索算法來判定對象是否存活的。這種算法的基木思路 是通過一系列名為“gc?roots”的對象作為起始點,從這些節(jié)點開始向下搜索, 搜索所走過的路徑稱為引用鏈,當(dāng)一個對象到gc?roots沒有任何引用鏈相連時, 就證明此對象是不可用的。在java語言里,可作為gc?roots的兌現(xiàn)包括下而幾
5、種:虛擬機(jī)棧(棧幀中的本地變量表)中引用的對彖。方法區(qū)中的類靜態(tài)屬性引用的對象。方法區(qū)小的常量引用的對象。 本地方法棧中jni (native方法)的引用對象。實際上,在根搜索算法中,要真正宣告一個對象死亡,至少要經(jīng)歷兩次標(biāo)記過程: 如果對象在進(jìn)行根搜索后發(fā)現(xiàn)沒有與gc?roots相連接的引用鏈,那它會被第一 次標(biāo)記并11進(jìn)行一次篩選,篩選的條件是此對象是否有必要執(zhí)行() 方法。當(dāng)對象沒有覆蓋finalize ()方法,或finalize ()方法已經(jīng)被虛擬機(jī) 調(diào)用過,虛擬機(jī)將這兩種情況都視為沒冇必耍執(zhí)行。如果該對彖被判定為冇必要 執(zhí)行finalize ()方法,那么這個對彖將會被放置在一個名
6、為f-queue隊列中, 并在稍后由一條由虛擬機(jī)自動建立的、低優(yōu)先級的finalizer線程去執(zhí)行 final ize ()方法。finalize ()方法是對象逃脫死亡命運(yùn)的最后一次機(jī)會(因 為一個對象的f inalizc ()方法最多只會被系統(tǒng)口動調(diào)用一次),稍后gc將對 f-queue屮的對彖進(jìn)行第二次小規(guī)模的標(biāo)記,如杲要在finalize ()方法屮成功 拯救口己,只要在finalize ()方法中讓該對象重引用鏈上的任何一個對象建 立關(guān)聯(lián)即可。而如果對象這吋還沒有關(guān)聯(lián)到任何鏈上的引用,那它就會被冋收掉。垃圾收集算法判定除了垃圾對象之后,便可以進(jìn)行垃圾回收了。下面介紹一些垃圾收集算法,
7、 由于垃圾收集算法的實現(xiàn)涉及大量的程序細(xì)節(jié),因此這里主要是闡明各算法的實 現(xiàn)思想,而不去細(xì)論算法的具體實現(xiàn)。? ?標(biāo)記一清除算法標(biāo)記一清除算法是最基礎(chǔ)的收集算法,它分為“標(biāo)記”和“清除”兩個階段:首 先標(biāo)記出所需回收的對象,在標(biāo)記完成后統(tǒng)一回收掉所冇被標(biāo)記的對彖,它的標(biāo) 記過程其實就是前面的根搜索算法中判定垃圾對彖的標(biāo)記過程。標(biāo)記一清除算法 的執(zhí)行情況如下圖所示:冋收前狀態(tài):存活對象可回收未使用?回收后狀態(tài):該算法有如下缺點:標(biāo)記和清除過程的效率都不高。標(biāo)記清除后會產(chǎn)生人量不連續(xù)的內(nèi)存碎片,空間碎片太多可能會導(dǎo)致,當(dāng)程序在以 后的運(yùn)行過程屮需要分配較人對象時無法找到足夠的連續(xù)內(nèi)存而不得不觸發(fā)另
8、一次 垃圾收集動作。? ?復(fù)制算法復(fù)制算法是針對標(biāo)記一清除算法的缺點,在其基礎(chǔ)上進(jìn)行改進(jìn)而得到的,它講課 用內(nèi)存按容量分為大小相等的兩塊,每次只使用其中的一塊,當(dāng)這一塊的內(nèi)存用 完了,就將述存活著的對彖復(fù)制到另外一塊內(nèi)存上而,然后再把已使用過的內(nèi)存 空間一次清理掉。復(fù)制算法有如下優(yōu)點:每次只對一塊內(nèi)存進(jìn)行回收,運(yùn)行高效。只需移動棧頂指針,按順序分配內(nèi)存即可,實現(xiàn)簡單。內(nèi)存回收時不用考慮內(nèi)存碎片的出現(xiàn)。它的缺點是:可一次性分配的最大內(nèi)存縮小了一半。復(fù)制算法的執(zhí)行情況如下圖所示:回收前狀態(tài):?回收后狀態(tài):存活對象可回收未使用保留區(qū)域? ?標(biāo)記一整理算法?復(fù)制算法比較適合于新生代,在老年代中,對象存
9、活率比較高,如果執(zhí)行較 多的復(fù)制操作,效率將會變低,所以老年代一般會選用其他算法,如標(biāo)記一整理 算法。該算法標(biāo)記的過程與標(biāo)記一清除算法中的標(biāo)記過程一樣,但對標(biāo)記后出的 垃圾對象的處理情況有所不同,它不是直接對可冋收對象進(jìn)行清理,而是讓所有 的對象都向一端移動,然后直接清理掉端邊界以外的內(nèi)存。標(biāo)記一整理算法的回 收情況如下所示:存活對象可回收未使用凹收前狀態(tài):收后狀態(tài):? ?分代收集當(dāng)前商業(yè)虛擬機(jī)的垃圾收集?都采用分代收集,它根據(jù)對象的存活周期的不同將 內(nèi)存劃分為幾塊,一般是把java堆分為新生代和老年代。在新生代中,每次垃 圾收集時都會發(fā)現(xiàn)有人量對象死去,只有少量存活,因此可選用復(fù)制算法來完成
10、 收集,而老年代中因為對象存活率高、沒有額外空間對它進(jìn)行分配擔(dān)保,就必須 使用標(biāo)記一清除算法或標(biāo)記一整理算法來進(jìn)行回收。垃圾收集器垃圾收集器是內(nèi)存回收算法的具體實現(xiàn),j4v4虛擬機(jī)規(guī)范中對垃圾收集器應(yīng)該 如何實現(xiàn)并沒有任何規(guī)定,因此不同廠商、不同版本的虛擬機(jī)所提供的垃圾收集 器都可能會冇很大的差別。sun?hotspot虛擬機(jī)1. 6版包含了如下收集器: serial> parnew、parallel?scavenge> cmsserial?01d> parallel?01do 這些 收集器以不同的組合形式配合工作來完成不同分代區(qū)的垃圾收集工作。垃圾回收分析?在用代碼分析z前
11、,我們對內(nèi)存的分配策略明確以下三點:對象優(yōu)先在eden分配。大對象直接進(jìn)入老年代。長期存活的對象將進(jìn)入老年代。?對垃圾回收策略說明以下兩點:新生代gc (minor gc):發(fā)生在新生代的垃圾收集動作,因為java対象大多都貝有 朝生夕滅的特性,因此minor gc非常頻繁,一般回收速度也比較快。 老年代gc (majorgc/fullgc):發(fā)生在老年代的gc,出現(xiàn)了 majorgc,經(jīng)常會 伴隨至少一次minor gco由于老年代屮的對象生命周期比較長,因此major gc并 不頻繁,一般都是等待老年代滿了后才進(jìn)行full gc,而且其速度一般會比minor gc 慢10倍以上。另外,如果
12、分配了 direct memory,在老年代中進(jìn)行full gc吋,會 順便清理掉direct memory中的廢棄對象。? ?下面我們來看如下代碼:public class slotgcpublic static void main(string args)byte holder = new byte32*1024*1024;system. gc ();代碼很簡單,就是向內(nèi)存屮填充了 32mb的數(shù)據(jù),然后通過虛擬機(jī)進(jìn)行垃圾收集。 在javac編譯后,我們執(zhí)行如下指令:java?-verbose :gc?slotgc來查看垃圾收 集的結(jié)果,得到如下輸出信息:gc?208k->134k(5
13、056k), ?0. 0017306?secs? ? full?gc?134k->134k(5056k),?0. 0121194?sccs? ? full?gc?32902k->32902k(37828k), ?0. 0094149?sec注意第三行,z前的數(shù)據(jù)表示垃圾回收前堆中存活對象所占用的內(nèi)存大 小,之后的數(shù)據(jù)表示垃圾回收堆中存活對象所山用的內(nèi)存大小,括號中的 數(shù)據(jù)表示堆內(nèi)存的總?cè)萘浚?. 0094149?sec表示垃圾冋收所用的時間。從結(jié)果中可以看出,system. gc()運(yùn)行后并沒有回收掉這32mb的內(nèi)存,這應(yīng) 該是意料z屮的結(jié)果,因為變量holder還處在作用域內(nèi),虛
14、擬機(jī)自然不會回收 掉holder引用的對彖所占用的內(nèi)存。我們把代碼修改如下:public class slotgcpublic static void main(string args)byte holder = new byte32*1024*1024; system gc ();加入花括號后holder的作用域被限制在了花括號之內(nèi),因此,在執(zhí)行system, gc ()時,holder引用已經(jīng)不能再被訪問,邏輯上來講,這次應(yīng)該會冋收掉holder 引用的對象所占的內(nèi)存。但查看垃圾回收情況時,輸出信息如下:gc?208k->134k(5056k), ?0. 0017100?sccs?
15、? full?gc?134k->134k(5056k),?0. 0125887?secs? ? full?gc?32902k->32902k(37828k), ?0. 0089226?secs很明顯,這32me的數(shù)據(jù)并沒有被冋收。下面我們再做如下修改:public class slotgcpublic static void main(string args)byte holder = new byte32*1024*1024;holder 二 null;system, gc ();這次得到的垃圾回收信息如下:? ? gc?208k->134k(5056k),?0. 0017
16、194?secs? ? full?gc?134k->134k(5056k), ?0. 0124656?secs? ? full?gc?32902k->134k(37828k), ?0. 0091637?secs說明這次holder引用的對象所占的內(nèi)存被回收了。我們慢慢來分析。首先明確一點:holder能否被回收的根本原因是局部變量表中的slot是否還存 冇關(guān)j*' holder數(shù)組對彖的引用。在第一次修改中,雖然在holder作用域z外進(jìn)行回收,但是在此z后,沒有對 局部變量表的讀寫操作,holder所占用的slot還沒有被其他變量所復(fù)用(回憶 java內(nèi)存區(qū)域與內(nèi)存溢出一
17、文中關(guān)于slot的講解),所以作為gc?roots 一部 分的局部變量表仍保持者對它的關(guān)聯(lián)。這種關(guān)聯(lián)沒有被及時打斷,因此gc收集 器不會將holder引用的對象內(nèi)存回收掉。?在第二次修改中,在gc收集器工作 前,手動將holder設(shè)置為null值,就把holder所占用的局部變量表中的slot 清空了,因此,這次gc收集器工作時將holder之前引用的對象內(nèi)存回收掉了。當(dāng)然,我們也可以用其他方法來將holder引用的對象內(nèi)存回收掉,只要復(fù)用 holder所占用的slot即可,比如在holder作用域z外執(zhí)行一次讀寫操作。為對象賦null值并不是控制變量回收的最好方法,以恰當(dāng)?shù)淖兞孔饔猛砜刂?
18、變量冋收時間才是最優(yōu)雅的解決辦法。另外,賦null值的操作在經(jīng)過虛擬機(jī)jit 編譯器優(yōu)化后會被消除掉,經(jīng)過jit編譯后,system, gc ()執(zhí)行時就可以正確 地回收掉內(nèi)存,而無需賦null值。性能調(diào)優(yōu)java虛擬機(jī)的內(nèi)存管理與垃圾收集是虛擬機(jī)結(jié)構(gòu)體系屮最重要的組成部分,對 程序(尤其服務(wù)器端)的性能和穩(wěn)定性有著非常重要的影響。性能調(diào)優(yōu)需要具體 情況具體分析,而且實際分析吋可能需要考慮的方面很多,這里僅就-些簡單常 用的情況作簡要介紹。我們可以通過給java虛擬機(jī)分恥超大堆(前提是物理機(jī)的內(nèi)存足夠大)來提升服務(wù) 器的響應(yīng)速度,但分配超人堆的前提是有把握把應(yīng)用程序的full?gc頻率控制得足 夠低,因為一次full?gc的時間造成比較長時間的停頓。控制full?gc頻率的關(guān)鍵是保證應(yīng)用屮絕人多數(shù)對象的生存周期不應(yīng)太長,尤其不能產(chǎn)生批最的、生命周期 長的大対象,這樣才能保證老年代的穩(wěn)定。 direct?memory在堆內(nèi)存外分配,而且二者均受限于物理機(jī)內(nèi)存,u成負(fù)相關(guān)關(guān)系, 因此分配超大堆時,如果用到了 nio機(jī)制分配使用了很多的direct?memory,則有 可能導(dǎo)致direct?memory的outofmemoryerror異常,這時可以通過 -xx:maxdirectmemory
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 脫靴器市場分析及投資價值研究報告
- 廢物的運(yùn)輸和貯藏行業(yè)相關(guān)項目經(jīng)營管理報告
- 農(nóng)業(yè)作物蟲害生物防治行業(yè)市場調(diào)研分析報告
- 不銹鋼冰塊產(chǎn)業(yè)鏈招商引資的調(diào)研報告
- 手動磨利器具產(chǎn)品供應(yīng)鏈分析
- 醫(yī)療器械物流行業(yè)營銷策略方案
- 電子蜂鳴器市場分析及投資價值研究報告
- 竹簾市場發(fā)展前景分析及供需格局研究預(yù)測報告
- 底褲服裝產(chǎn)業(yè)鏈招商引資的調(diào)研報告
- 老繭銼刀市場發(fā)展前景分析及供需格局研究預(yù)測報告
- 二年級上冊數(shù)學(xué)練習(xí)題集及作業(yè)設(shè)計意圖
- 設(shè)備稼動率如何計算
- 三方共管賬戶資金監(jiān)管協(xié)議書
- 物權(quán)法知識點
- jtestF級詞匯
- 定期清洗消毒空調(diào)及通風(fēng)設(shè)施的制度
- 強(qiáng)直性脊柱炎的護(hù)理PPT
- 濕、熱敷法操作規(guī)程及評分標(biāo)準(zhǔn)
- 護(hù)理質(zhì)量改善項目申報書
- 熱軋H型鋼理論重量表
- 正片大片-新片速遞
評論
0/150
提交評論