中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

怎么理解JVM1.4.1版本中的JVM垃圾收集策略

本篇文章給大家分享的是有關(guān)怎么理解JVM1.4.1版本中的JVM垃圾收集策略,小編覺得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

創(chuàng)新互聯(lián)建站為您提適合企業(yè)的網(wǎng)站設(shè)計(jì)?讓您的網(wǎng)站在搜索引擎具有高度排名,讓您的網(wǎng)站具備超強(qiáng)的網(wǎng)絡(luò)競爭力!結(jié)合企業(yè)自身,進(jìn)行網(wǎng)站設(shè)計(jì)及把握,最后結(jié)合企業(yè)文化和具體宗旨等,才能創(chuàng)作出一份性化解決方案。從網(wǎng)站策劃到成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作, 我們的網(wǎng)頁設(shè)計(jì)師為您提供的解決方案。

我們分析了引用計(jì)數(shù)、復(fù)制、標(biāo)記-清除和標(biāo)記-整理這些經(jīng)典的JVM垃圾收集技術(shù)。其中每一種方法在特定條件下都有其優(yōu)點(diǎn)和缺點(diǎn)。JVM1.2及以后版本使用的技術(shù)稱為分代JVM垃圾收集(generationalgarbagecollection),它結(jié)合了這兩種技術(shù)以結(jié)合二者的長處,結(jié)果就是對象分配開銷非常小。

JVM1.4.1中的垃圾收集

我們分析了引用計(jì)數(shù)、復(fù)制、標(biāo)記-清除和標(biāo)記-整理這些經(jīng)典的JVM垃圾收集技術(shù)。其中每一種方法在特定條件下都有其優(yōu)點(diǎn)和缺點(diǎn)。例如,當(dāng)有很多對象成為垃圾時(shí),復(fù)制可以做得很好,但是有許多長壽對象時(shí)它就變得很糟(要反復(fù)復(fù)制它們)。相反,標(biāo)記-整理對于長壽對象可以做得很好(只復(fù)制一次),但是當(dāng)有許多短壽對象時(shí)就沒有那么好了。JVM1.2及以后版本使用的技術(shù)稱為分代JVM垃圾收集(generationalgarbagecollection),它結(jié)合了這兩種技術(shù)以結(jié)合二者的長處,結(jié)果就是對象分配開銷非常小。

老對象和年輕對象

在任何一個(gè)應(yīng)用程序堆中,一些對象在創(chuàng)建后很快就成為垃圾,另一些則在程序的整個(gè)運(yùn)行期間一直保持生存。經(jīng)驗(yàn)分析表明,對于大多數(shù)面向?qū)ο蟮恼Z言,包括Java語言,絕大多數(shù)對象――可以多達(dá)98%(這取決于您對年輕對象的衡量標(biāo)準(zhǔn))是在年輕的時(shí)候死亡的??梢杂脮r(shí)鐘秒數(shù)、對象分配以后?h內(nèi)存管理子系統(tǒng)分配的總字節(jié)或者對象分配后經(jīng)歷的JVM垃圾收集的次數(shù)來計(jì)算對象的壽命。但是不管您如何計(jì)量,分析表明了同一件事――大多數(shù)對象是在年輕的時(shí)候死亡的。大多數(shù)對象在年輕時(shí)死亡這一事實(shí)對于收集器的選擇很有意義。特別是,當(dāng)大多數(shù)對象在年輕時(shí)死亡時(shí),復(fù)制收集器可以執(zhí)行得相當(dāng)好,因?yàn)閺?fù)制收集器完全不訪問死亡的對象,它們只是將活的對象復(fù)制到另一個(gè)堆區(qū)域中,然后一次性收回所有的剩余空間。

那些經(jīng)歷過***次JVM垃圾收集后仍能生存的對象,很大部分會成為長壽的或者***的對象。根據(jù)短壽對象和長壽對象的混合比例,不同JVM垃圾收集策略的性能會有非常大的差別。當(dāng)大多數(shù)對象在年輕時(shí)死亡時(shí),復(fù)制收集器可以工作得很好,因?yàn)槟贻p時(shí)死亡的對象永遠(yuǎn)不需要復(fù)制。不過,復(fù)制收集器處理長壽對象卻很糟糕,它要從一個(gè)半空間向另一個(gè)半空間反復(fù)來回復(fù)制這些對象。相反,標(biāo)記-整理收集器對于長壽對象可以工作得很好,因?yàn)殚L壽對象趨向于沉在堆的底部,從而不用再復(fù)制。不過,標(biāo)記-清除和標(biāo)記-理整收集器要做很多額外的分析死亡對象的工作,因?yàn)樵谇宄A段它們必須分析堆中的每一個(gè)對象。

分代收集

分代收集器(generializationalcollector)將堆分為多個(gè)代。在年輕的代中創(chuàng)建對象,滿足某些提升標(biāo)準(zhǔn)的對象,如經(jīng)歷了特定次數(shù)JVM垃圾收集的對象,將被提升到下一更老的代。分代收集器對不同的代可以自由使用不同的收集策略,對各代分別進(jìn)行JVM垃圾收集。

小的收集

分代收集的一個(gè)優(yōu)點(diǎn)是它不同時(shí)收集所有的代,因此可以使JVM垃圾收集暫停更短。當(dāng)分配器不能滿足分配請求時(shí),它首先觸發(fā)一個(gè)小的收集(minorcollection),它只收集最年輕的代。因?yàn)槟贻p代中的許多對象已經(jīng)死亡,復(fù)制收集器完全不用分析死亡的對象,所以小的收集的暫停可以相當(dāng)短并通??梢曰厥沾罅康亩芽臻g。如果小的收集釋放了足夠的堆空間,那么用戶程序就可以立即恢復(fù)。如果它不能釋放足夠的堆空間,那么它就繼續(xù)收集上一代,直到回收了足夠的內(nèi)存。(在JVM垃圾收集器進(jìn)行了全部收集以后仍不能回收足夠的內(nèi)存時(shí),它將擴(kuò)展堆或者拋出OutOfMemoryError)。

代間引用

跟蹤JVM垃圾收集器,如復(fù)制、標(biāo)記-清除和標(biāo)記-整理等JVM垃圾收集器,都是從根集(rootset)開始掃描,遍歷對象間的引用,直到訪問了所有活的對象。

分代跟蹤收集器從根集開始,但是并不遍歷指向更老一代中對象的引用,這減少了要跟蹤的對象圖的大小。但是這也帶來一個(gè)問題――如果更老一代中的對象引用一個(gè)不能通過從根開始的所有其他引用鏈到達(dá)的更年輕的對象該怎么辦?

為了解決這個(gè)問題,分代收集器必須顯式地跟蹤從老對象到年輕對象的引用并將這些老到年輕的引用加入到小的收集的根集中。有兩種創(chuàng)建從老對象到年輕對象的引用的方法。要么是將老對象中包含的引用修改為指向年輕對象,要么是將引用其他年輕對象的年輕對象提升為更老的一代。

跟蹤代間引用

不管一個(gè)老到年輕的引用是通過提升還是指針修改創(chuàng)建的,JVM垃圾收集器在進(jìn)行小的收集時(shí)需要有全部老到年輕的引用。做到這一點(diǎn)的一種方法是跟蹤老的代,但是這顯然有很大的開銷。更好的一種方法是線性掃描老的代以查找對年輕對象的引用。這種方法比跟蹤更快并有更好的區(qū)域性(locality),但是仍然有很大的工作量。

賦值函數(shù)(mutator)和JVM垃圾收集器可以共同工作以在創(chuàng)建老到年輕的引用時(shí)維護(hù)它們的完整列表。當(dāng)對象提升為更老一代時(shí),JVM垃圾收集器可以記錄所有由于這種提升而創(chuàng)建的老到年輕的引用,這樣就只需要跟蹤由指針修改所創(chuàng)建的代間引用。

JVM垃圾收集器可以有幾種方法跟蹤由于修改現(xiàn)有對象中的引用而產(chǎn)生的老到年輕的引用。它可以使用在引用計(jì)數(shù)收集器中維護(hù)引用計(jì)數(shù)的同樣方法(編譯器可以生成圍繞指針賦值的附加指令)跟蹤它們,也可以在老一代堆上使用虛擬內(nèi)存保護(hù)以捕獲向老對象的寫入。另一種可能更有效的虛擬內(nèi)存方法是在老一代堆中使用頁修改臟位(pagemodificationdirtybit),以確定為找到包含老到年輕指針的對象時(shí)要掃描的塊。

用一點(diǎn)小技巧,就可以避免跟蹤每一個(gè)指針修改并檢查它是否跨越代邊界的開銷。例如,不需要跟蹤針對本地或者靜態(tài)變量的存儲,因?yàn)樗鼈円呀?jīng)是根集的一部分了。也可以避免跟蹤存儲在某些構(gòu)造函數(shù)中的指針,這些構(gòu)造函數(shù)只用于初始化新建對象的字段(即所謂初始化存儲(initializingstores)),因?yàn)椋◣缀酰┧袑ο蠖际欠峙涞侥贻p代中。不管是什么情況,運(yùn)行庫都必須維護(hù)一個(gè)老對象到年輕對象的引用集并在收集年輕代時(shí)將這些引用添加到根集中。

在圖1中,箭頭表示堆中對象間的引用。紅色箭頭表示必須添加到根集中供小的收集使用的老到年輕的引用。藍(lán)色箭頭表示從根集或者年輕代到老對象的引用,在只收集年輕代時(shí)不需要跟蹤它們。

怎么理解JVM1.4.1版本中的JVM垃圾收集策略

卡片標(biāo)記

SunJDK使用一種稱為卡片標(biāo)記(cardmarking)算法的改進(jìn)算法以標(biāo)識對老一代對象的字段中包含的指針的修改。在這種方法中,堆分為一組卡片,每個(gè)卡片一般都小于一個(gè)內(nèi)存頁。JVM維護(hù)著一個(gè)卡片映射,對應(yīng)于堆中的每一個(gè)卡片都有一個(gè)位(在某些實(shí)現(xiàn)中是一個(gè)字節(jié))。每次修改堆中對象中的指針字段時(shí),就在卡片映射中設(shè)置對應(yīng)那張卡片的相應(yīng)位。在JVM垃圾收集時(shí),就對與老一代中卡片相關(guān)聯(lián)的標(biāo)記位進(jìn)行檢查,對臟的卡片掃描以尋找對年輕代有引用的對象。然后清除標(biāo)記位??ㄆ瑯?biāo)記有幾項(xiàng)開銷――卡片映射所需的額外空間、對每一個(gè)指針存儲所做的額外工作,以及在JVM垃圾收集時(shí)做的額外工作。對每一個(gè)非初始化堆指針存儲,卡片標(biāo)記算法可以只增加兩到三個(gè)機(jī)器指令,并要求在小的收集時(shí)對所有臟卡片上的對象進(jìn)行掃描。

JDK1.4.1默認(rèn)收集器

在默認(rèn)情況下,JDK1.4.1將堆分為兩部分,一個(gè)年輕的代和一個(gè)老的代(實(shí)際上,還有第三部分――***空間,它用于存儲裝載的類和方法對象)。借助于復(fù)制收集器,年輕的代又分為一個(gè)創(chuàng)建空間(通常稱為Eden)和兩個(gè)生存半空間。

老的代使用標(biāo)記-整理收集器。對象在經(jīng)歷了幾次復(fù)制后提升到老的代。小的收集將活的對象從Eden和一個(gè)生存半空間復(fù)制到另一個(gè)生存半空間,并可能提升一些對象到老的代。大的收集(majorcollection)既會收集年輕的代,也會收集老的代。System.gc()方法總是觸發(fā)一個(gè)大的收集,這就是應(yīng)該盡量少用(如果不能完全不用的話)System.gc()的原因之一,因?yàn)榇蟮氖占刃〉氖占ㄙM(fèi)長得多的時(shí)間。沒有辦法以編程方式觸發(fā)小的收集。

其他收集選項(xiàng)

除了默認(rèn)情況下使用的復(fù)制收集器和標(biāo)記-整理收集器,JDK1.4.1還包含其他四種JVM垃圾收集算法,每一種適用于不同的目的。JDK1.4.1包含一個(gè)增量收集器(自JDK1.2就已經(jīng)出現(xiàn)了)和三種在多處理器系統(tǒng)中進(jìn)行更有效收集的新收集器――并行復(fù)制收集器、并行清除(scavenging)收集器和并發(fā)標(biāo)記-清除收集器。這些新收集器是為了解決在多處理器系統(tǒng)中JVM垃圾收集器成為伸縮性瓶頸這一問題的。圖2顯示了在什么時(shí)候選擇備用收集選項(xiàng)的指導(dǎo)。

怎么理解JVM1.4.1版本中的JVM垃圾收集策略

增量收集

增量收集選項(xiàng)自1.2起就成為JDK的一部分。增量收集減少了JVM垃圾收集暫停,以犧牲吞吐能力為代價(jià),這使它只在更短的收集暫停非常重要時(shí)才值得考慮,如接近實(shí)時(shí)的系統(tǒng)。

Train算法是JDK用于增量收集的算法,它在堆中老的代和年輕的代之間創(chuàng)建一個(gè)新區(qū)域。這些堆區(qū)域劃分為“火車(train)”,每個(gè)火車又分為一系列的“車廂(car)”。每個(gè)車廂可以分別收集。結(jié)果,每個(gè)火車車廂組成單獨(dú)的一代,這意味著不但要跟蹤老到年輕的引用,而且還要跟蹤從老的火車到年輕的火車以及老的車廂到年輕的車廂的引用。這為賦值函數(shù)(mutator)和JVM垃圾收集器帶來了大量的額外工作,但是可以得到更短的收集暫停。

并行收集器和并發(fā)收集器

JDK1.4.1中新的收集器都是為解決多處理器系統(tǒng)中JVM垃圾收集器的問題而設(shè)計(jì)的。因?yàn)榇蠖鄶?shù)JVM垃圾收集算法會在一段時(shí)間里使系統(tǒng)停止,單線程的收集器很快會成為伸縮性瓶頸,因?yàn)樵贘VM垃圾收集器將用戶程序線程掛起時(shí),除了一個(gè)處理器之外,其他的處理器都是空閑的。新收集器中的兩個(gè)――并行復(fù)制收集器和并發(fā)標(biāo)記-清除收集器――設(shè)計(jì)為減少收集暫停時(shí)間。另一個(gè)是并行清除收集器,它是為在大堆上的更高吞吐能力而設(shè)計(jì)的。

并行復(fù)制收集器用JVM選項(xiàng)-XX:+UseParNewGC啟用,是一個(gè)年輕代復(fù)制收集器,它將JVM垃圾收集的工作分為與CPU數(shù)量一樣多的線程。并發(fā)標(biāo)記-清除收集器由-XX:+UseConcMarkSweepGC選項(xiàng)啟用,它是一個(gè)老代標(biāo)記-清除收集器,它在初始標(biāo)記階段(及在以后暫短重新標(biāo)記階段)暫短地停止整個(gè)系統(tǒng),然后恢復(fù)用戶程序,同時(shí)JVM垃圾收集器線程與用戶程序并發(fā)地執(zhí)行。并行復(fù)制收集器和并發(fā)標(biāo)記-清除收集器基本上是默認(rèn)的復(fù)制收集器和標(biāo)記-整理收集器的并發(fā)版本。由-XX:+UseParallelGC啟用的并行清除收集器是年輕代收集器,針對多處理器系統(tǒng)上非常大(吉字節(jié)以及更大的)堆進(jìn)行了優(yōu)化。

選擇一種算法

有六種算法可以選擇,您可能不知道要使用哪一種。圖2提供了一些指導(dǎo),將收集器分為單線程和并發(fā)的,以及分為短暫停和高吞吐能力的。只要您掌握了應(yīng)用程序和部署環(huán)境的信息,就足以選擇合適的算法。對于許多應(yīng)用程序,默認(rèn)的收集器可以工作得很好――因此如果您沒有性能問題,那么就沒必要加入更多的復(fù)雜性。不過,如果您的應(yīng)用程序是部署在多處理器系統(tǒng)上或者使用非常大的堆,那么改變收集器選項(xiàng)可能會有巨大的性能提升。

微調(diào)JVM垃圾收集器

JDK1.4.1還包括大量的微調(diào)JVM垃圾收集的選項(xiàng)。調(diào)整這些選項(xiàng)并衡量它們的效果可能會花費(fèi)您大量時(shí)間,因此在試圖微調(diào)JVM垃圾收集器之前先對您的應(yīng)用程序進(jìn)行徹底的配置(profile)和優(yōu)化,這樣您的微調(diào)工作可能會得到更好的結(jié)果。

微調(diào)JVM垃圾收集首先要做的是檢查冗長的GC輸出。這會使您得到JVM垃圾收集操作的頻率、定時(shí)和持續(xù)時(shí)間等信息。最簡單的JVM垃圾收集微調(diào)就是擴(kuò)大***堆的大小(-Xmx)。隨著堆的增大,復(fù)制收集會變得更有效,所以在增大堆時(shí),您就減少了每個(gè)對象的收集成本。除了增加***堆的大小,還可以用選項(xiàng)-XX:NewRatio增加分配給年輕代的空間份額。也可以用-Xmn選項(xiàng)顯式指定年輕代的大小。

隨著JVM的發(fā)展,默認(rèn)JVM垃圾收集器變得越來越好了。JDK1.2及以后版本所使用的分代JVM垃圾收集器提供了比早期JDK所使用的標(biāo)記-清除-整理收集器好得多的分配和收集性能。JDK1.4.1通過增加新的針對多處理器系統(tǒng)和非常大的堆的多線程收集選項(xiàng),進(jìn)一步改進(jìn)了JVM垃圾收集的效率。

以上就是怎么理解JVM1.4.1版本中的JVM垃圾收集策略,小編相信有部分知識點(diǎn)可能是我們?nèi)粘9ぷ鲿姷交蛴玫降?。希望你能通過這篇文章學(xué)到更多知識。更多詳情敬請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

網(wǎng)站題目:怎么理解JVM1.4.1版本中的JVM垃圾收集策略
文章網(wǎng)址:http://www.rwnh.cn/article48/gcgjep.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供ChatGPT、網(wǎng)站改版、外貿(mào)網(wǎng)站建設(shè)做網(wǎng)站、網(wǎng)站設(shè)計(jì)服務(wù)器托管

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

綿陽服務(wù)器托管
武冈市| 晴隆县| 钦州市| 鄂尔多斯市| 崇州市| 白银市| 红河县| 虹口区| 许昌县| 会昌县| 南投县| 秦安县| 林口县| 股票| 郁南县| 嘉荫县| 乃东县| 治县。| 永兴县| 深州市| 昌宁县| 工布江达县| 巴楚县| 龙游县| 贵阳市| 肥乡县| 西华县| 岐山县| 雷波县| 西华县| 阿克| 庄浪县| 尼木县| 景谷| 屯昌县| 青田县| 新绛县| 丹江口市| 海淀区| 眉山市| 丹寨县|