偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

JVM1.4.1版本中的JVM垃圾收集策略

開(kāi)發(fā) 后端
每一種垃圾收集技術(shù)在特定條件下都有其優(yōu)點(diǎn)和缺點(diǎn),這里向大家描述一下JVM1.4.1中的垃圾收集,重點(diǎn)說(shuō)明一下分代垃圾收集和并發(fā)垃圾收集,希望對(duì)你的學(xué)習(xí)有所幫助。

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

JVM1.4.1中的垃圾收集

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

老對(duì)象和年輕對(duì)象

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

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

分代收集

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

小的收集

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

代間引用

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

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

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

跟蹤代間引用

不管一個(gè)老到年輕的引用是通過(guò)提升還是指針修改創(chuàng)建的,JVM垃圾收集器在進(jìn)行小的收集時(shí)需要有全部老到年輕的引用。做到這一點(diǎn)的一種方法是跟蹤老的代,但是這顯然有很大的開(kāi)銷(xiāo)。更好的一種方法是線(xiàn)性?huà)呙枥系拇圆檎覍?duì)年輕對(duì)象的引用。這種方法比跟蹤更快并有更好的區(qū)域性(locality),但是仍然有很大的工作量。

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

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

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

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

 

代間引用

卡片標(biāo)記

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

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

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

老的代使用標(biāo)記-整理收集器。對(duì)象在經(jīng)歷了幾次復(fù)制后提升到老的代。小的收集將活的對(duì)象從Eden和一個(gè)生存半空間復(fù)制到另一個(gè)生存半空間,并可能提升一些對(duì)象到老的代。大的收集(majorcollection)既會(huì)收集年輕的代,也會(huì)收集老的代。System.gc()方法總是觸發(fā)一個(gè)大的收集,這就是應(yīng)該盡量少用(如果不能完全不用的話(huà))System.gc()的原因之一,因?yàn)榇蟮氖占刃〉氖占ㄙM(fèi)長(zhǎng)得多的時(shí)間。沒(méi)有辦法以編程方式觸發(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垃圾收集器成為伸縮性瓶頸這一問(wèn)題的。圖2顯示了在什么時(shí)候選擇備用收集選項(xiàng)的指導(dǎo)。

JVM1.4.1垃圾收集選項(xiàng)

增量收集

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

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

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

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

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

選擇一種算法

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

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

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

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

結(jié)束語(yǔ)

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

【編輯推薦】

  1. JVM內(nèi)存溢出的兩大類(lèi)型及解決方案
  2. Tomcat配置JVM參數(shù)巧妙方法
  3. JVM基礎(chǔ):解析JVM分代垃圾回收策略
  4. JVM for Linux JIT診斷技術(shù)簡(jiǎn)介
  5. 巧解IBM JVM for Linux onPOWER性能調(diào)優(yōu)

 

責(zé)任編輯:佚名 來(lái)源: javaeye.com
相關(guān)推薦

2010-02-22 08:58:35

JVM內(nèi)存模型垃圾收集

2024-03-15 08:04:30

G1CMSJVM

2010-09-27 09:01:26

JVM分代垃圾回收

2011-12-20 10:43:21

Java

2024-08-26 08:58:50

2024-12-30 08:03:08

2011-12-05 12:51:58

JVMJava

2010-01-06 09:28:08

JVM分代垃圾回收

2017-09-21 14:40:06

jvm算法收集器

2022-05-06 22:13:56

JVM垃圾收集算法

2009-12-30 10:14:29

JVM垃圾回收

2023-08-08 10:29:55

JVM優(yōu)化垃圾回收

2022-06-22 09:54:45

JVM垃圾回收Java

2022-04-19 11:25:31

JVMZGC垃圾收集器

2024-03-14 09:00:00

2010-09-26 16:42:04

JVM內(nèi)存組成JVM垃圾回收

2022-06-10 07:13:29

JVM垃圾回收

2022-03-21 11:33:11

JVM垃圾回收器垃圾回收算法

2010-09-27 09:23:42

JVM調(diào)優(yōu)

2010-09-25 15:33:19

JVM垃圾回收
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)