資源描述:
《【每日一步】深入java垃圾回收機(jī)制和內(nèi)存泄露說不》由會(huì)員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在應(yīng)用文檔-天天文庫。
1、1.JVM的gc概述 gc即垃圾收集機(jī)制是指jvm用于釋放那些不再使用的對象所占用的內(nèi)存。java語言并不要求jvm有g(shù)c,也沒有規(guī)定gc如何工作。不過常用的jvm都有g(shù)c,而且大多數(shù)gc都使用類似的算法管理內(nèi)存和執(zhí)行收集操作。 在充分理解了垃圾收集算法和執(zhí)行過程后,才能有效的優(yōu)化它的性能。有些垃圾收集專用于特殊的應(yīng)用程序。比如,實(shí)時(shí)應(yīng)用程序主要是為了避免垃圾收集中斷,而大多數(shù)OLTP(聯(lián)機(jī)事務(wù)處理系統(tǒng))應(yīng)用程序則注重整體效率。理解了應(yīng)用程序的工作負(fù)荷和jvm支持的垃圾收集算法,便可以進(jìn)行優(yōu)化配置垃圾收集器?! ±占哪康脑谟谇宄辉偈褂玫膶ο?。gc通過確定
2、對象是否被活動(dòng)對象引用來確定是否收集該對象。gc首先要判斷該對象是否是時(shí)候可以收集。兩種常用的方法是引用計(jì)數(shù)和對象引用遍歷?! ?.1.引用計(jì)數(shù) 引用計(jì)數(shù)存儲(chǔ)對特定對象的所有引用數(shù),也就是說,當(dāng)應(yīng)用程序創(chuàng)建引用以及引用超出范圍時(shí),jvm必須適當(dāng)增減引用數(shù)。當(dāng)某對象的引用數(shù)為0時(shí),便可以進(jìn)行垃圾收集。 1.2.對象引用遍歷 早期的jvm使用引用計(jì)數(shù),現(xiàn)在大多數(shù)jvm采用對象引用遍歷。對象引用遍歷從一組對象開始,沿著整個(gè)對象圖上的每條鏈接,遞歸確定可到達(dá)(reachable)的對象。如果某對象不能從這些根對象的一個(gè)(至少一個(gè))到達(dá),則將它作為垃圾收集。在對象遍歷階
3、段,gc必須記住哪些對象可以到達(dá),以便刪除不可到達(dá)的對象,這稱為標(biāo)記(marking)對象?! ∠乱徊?,gc要?jiǎng)h除不可到達(dá)的對象。刪除時(shí),有些gc只是簡單的掃描堆棧,刪除未標(biāo)記的未標(biāo)記的對象,并釋放它們的內(nèi)存以生成新的對象,這叫做清除(sweeping)。這種方法的問題在于內(nèi)存會(huì)分成好多小段,而它們不足以用于新的對象,但是組合起來卻很大。因此,許多gc可以重新組織內(nèi)存中的對象,并進(jìn)行壓縮(compact),形成可利用的空間。 為此,gc需要停止其他的活動(dòng)。這種方法意味著所有與應(yīng)用程序相關(guān)的工作停止,只有g(shù)c運(yùn)行。結(jié)果,在響應(yīng)期間增減了許多混雜請求。另外,更復(fù)雜的g
4、c不斷增加或同時(shí)運(yùn)行以減少或者清除應(yīng)用程序的中斷。有的gc使用單線程完成這項(xiàng)工作,有的則采用多線程以增加效率。2.幾種垃圾回收機(jī)制 2.1.標(biāo)記-清除收集器 這種收集器首先遍歷對象圖并標(biāo)記可到達(dá)的對象,然后掃描堆棧以尋找未標(biāo)記對象并釋放它們的內(nèi)存。這種收集器一般使用單線程工作并停止其他操作?! ?.2.標(biāo)記-壓縮收集器 有時(shí)也叫標(biāo)記-清除-壓縮收集器,與標(biāo)記-清除收集器有相同的標(biāo)記階段。在第二階段,則把標(biāo)記對象復(fù)制到堆棧的新域中以便壓縮堆棧。這種收集器也停止其他操作?! ?.3.復(fù)制收集器 這種收集器將堆棧分為兩個(gè)域,常稱為半空間。每次僅使用一半的空間,jv
5、m生成的新對象則放在另一半空間中。gc運(yùn)行時(shí),它把可到達(dá)對象復(fù)制到另一半空間,從而壓縮了堆棧。這種方法適用于短生存期的對象,持續(xù)復(fù)制長生存期的對象則導(dǎo)致效率降低。 2.4.增量收集器 增量收集器把堆棧分為多個(gè)域,每次僅從一個(gè)域收集垃圾。這會(huì)造成較小的應(yīng)用程序中斷?! ?.5.分代收集器 這種收集器把堆棧分為兩個(gè)或多個(gè)域,用以存放不同壽命的對象。jvm生成的新對象一般放在其中的某個(gè)域中。過一段時(shí)間,繼續(xù)存在的對象將獲得使用期并轉(zhuǎn)入更長壽命的域中。分代收集器對不同的域使用不同的算法以優(yōu)化性能?! ?.6.并發(fā)收集器 并發(fā)收集器與應(yīng)用程序同時(shí)運(yùn)行。這些收集器在某點(diǎn)
6、上(比如壓縮時(shí))一般都不得不停止其他操作以完成特定的任務(wù),但是因?yàn)槠渌麘?yīng)用程序可進(jìn)行其他的后臺(tái)操作,所以中斷其他處理的實(shí)際時(shí)間大大降低?! ?.7.并行收集器 并行收集器使用某種傳統(tǒng)的算法并使用多線程并行的執(zhí)行它們的工作。在多cpu機(jī)器上使用多線程技術(shù)可以顯著的提高java應(yīng)用程序的可擴(kuò)展性。3.SunHotSpot 3.1JVM堆大小的調(diào)整 SunHotSpot1.4.1使用分代收集器,它把堆分為三個(gè)主要的域:新域、舊域以及永久域。Jvm生成的所有新對象放在新域中。一旦對象經(jīng)歷了一定數(shù)量的垃圾收集循環(huán)后,便獲得使用期并進(jìn)入舊域。在永久域中jvm則存儲(chǔ)clas
7、s和method對象。就配置而言,永久域是一個(gè)獨(dú)立域并且不認(rèn)為是堆的一部分。 下面介紹如何控制這些域的大小??墒褂?Xms和-Xmx控制整個(gè)堆的原始大小或最大值?! ∠旅娴拿钍前殉跏即笮≡O(shè)置為128M: java–Xms128m –Xmx256m為控制新域的大小,可使用-XX:NewRatio設(shè)置新域在堆中所占的比例?! ∠旅娴拿畎颜麄€(gè)堆設(shè)置成128m,新域比率設(shè)置成3,即新域與舊域比例為1:3,新域?yàn)槎训?/4或32M:java–Xms128m–Xmx128m–XX:NewRatio=3可使用-XX:NewSize和-XX:MaxNewsize設(shè)置新