jvm資料

關(guān)于Hotspot TM Java TM虛擬機(jī)中的

垃圾收集的常見(jiàn)問(wèn)題

本文檔描述了 Java( tm ) HotSpot ( tm ) 虛擬機(jī)的行為。但是,此行為不是 VM 規(guī)范的一部分,并且在未來(lái)的版本中可能會(huì)發(fā)生變化。此外,這里描述的 行為是通用行為,并不適用于所有 Java 應(yīng)用程序的執(zhí)行。

1.HotSpot(tm) 中的分代收集器是如何實(shí)現(xiàn)的?

HotSpot 中的默認(rèn)收集器有兩代:年輕代和老年代。大多數(shù)分配都是在年輕一代中完成的。年輕代針對(duì)生命周期相對(duì)于集合之間的間隔較短的對(duì)象進(jìn)行了優(yōu)化。在年輕代中多次收集的對(duì)象被移動(dòng)到終身代。年輕代通常更小,并且被更頻繁地收集。終身代通常較大且收集頻率較低。

年輕代收集器是一個(gè)復(fù)制收集器。年輕代分為 3 個(gè)空間:eden-space、to-space 和 from-space。分配是從 eden-space 和 from-space 完成的。當(dāng)這些已滿時(shí),年輕一代的收集就完成了。期望大多數(shù)對(duì)象都是垃圾,并且任何幸存的對(duì)象都可以復(fù)制到空間。如果存活對(duì)象的數(shù)量超過(guò)了 to-space 的容量,剩余的對(duì)象將被復(fù)制到老年代。可以選擇并行收集年輕代。

使用標(biāo)記-掃描-緊湊收集來(lái)收集終身代。有一個(gè)選項(xiàng)可以同時(shí)收集終身代。

-XX:MaxNewSize 的相關(guān)性是什么?-XX:NewSize 和 -XX:MaxNewSize 之間的差異會(huì)在哪里增長(zhǎng),Eden 或 Survivor Spaces?

年輕代由一個(gè)策略設(shè)置,該策略從下到上由 NewSize 限制大小,從上到下由 MaxNewSize 限制大小。隨著年輕一代從 NewSize 增長(zhǎng)到 MaxNewSize,伊甸園和幸存者空間都在增長(zhǎng)。

是否所有 eden-space 對(duì)象都移入了幸存者空間,以便在一次次 gc 之后,eden-space 是空的?

是的。如果 eden 中的所有活動(dòng)對(duì)象都無(wú)法放入幸存者空間,則剩余的活動(dòng)對(duì)象將被提升到老年代。

當(dāng)使用 -XX: TargetSurvivorRatio =90 時(shí),這會(huì)留下百分之十的空間用于從伊甸園中移動(dòng)對(duì)象嗎?

不。這意味著選擇了一個(gè) 任期閾值,以便根據(jù)上次次要收集中清除的內(nèi)容的年齡,應(yīng)該使用近 90% 的幸存者大小。從幸存者空間或伊甸園中清除的實(shí)際數(shù)量可能或多或少。

TargetSurvivorRatio 通常不會(huì)產(chǎn)生很大的影響。

如果 eden-space 中的對(duì)象需要的空間多于 to-survivor 空間中可用的空間,eden-space 對(duì)象是否會(huì)優(yōu)先于 from-survivor 空間對(duì)象?幸存者太空物體的年齡如何影響晉升?

在這里,來(lái)自伊甸園的東西和來(lái)自幸存者空間的東西沒(méi)有區(qū)別。次要收集完成后,伊甸園和來(lái)自幸存者的空間都是空的。如果 to-survivor 空間被填滿,任何剩余的對(duì)象都將直接提升到老年代,無(wú)論它們的年齡或來(lái)源如何。

在 NewSize 和 NewRatio 之間哪個(gè)選項(xiàng)優(yōu)先?

在 jdk 1.4.1 及更高版本中,兩者都沒(méi)有嚴(yán)格的優(yōu)先級(jí)。使用 NewSize 的最大值和使用 NewRatio 計(jì)算的大小。公式是

min (MaxNewSize, max (NewSize, heap/(NewRatio+1)))

2.永久代的規(guī)模應(yīng)該如何確定?

永久代用于保存 VM 本身的反射,例如類對(duì)象和方法對(duì)象。這些反射對(duì)象被直接分配到永久代,并且它的大小獨(dú)立于其他代。通常,可以忽略這一代的大小,因?yàn)槟J(rèn)大小已經(jīng)足夠了。但是,加載許多類的程序可能需要更大的永久代。

3.如何判斷永久代是否已滿?

從 1.4.2 開(kāi)始 -XX:+PrintGCDetails 將打印有關(guān)在每次垃圾回收時(shí)收集的堆的所有部分的信息。完整的收藏

[Full GC [Tenured: 30437K->33739K(280576K), 0.7050569 secs] 106231K->33739K(362112K), [Perm : 2919K->2919K(16384K)], 0.7052334 secs]

這個(gè)例子表明,永久代收集的很少(從收集前使用的 2919K 變?yōu)槭占笫褂玫?2919K),永久代的當(dāng)前大小為 16384K。

4.如何增加永久代的大???

使用命令行選項(xiàng) -XX:MaxPermSize=<desired size>

5.我如何知道正在加載或卸載哪些類?

使用命令行選項(xiàng) -XX:+ TraceClassloading和 -XX:+ TraceClassUnloading

6.年輕一代的最佳尺寸是多少?

年輕代的大小應(yīng)該足夠大,以便短期對(duì)象有機(jī)會(huì)在下一次年輕代收集之前死亡。這是一個(gè)權(quán)衡,因?yàn)楦蟮哪贻p代將允許對(duì)象有更多時(shí)間死亡,但也可能需要更長(zhǎng)的時(shí)間來(lái)收集。試驗(yàn)?zāi)贻p代的大小以優(yōu)化年輕代收集時(shí)間或 應(yīng)用程序吞吐量。

7.如果我的應(yīng)用程序有中長(zhǎng)壽命的對(duì)象,我該怎么辦?

在年輕代集合中存活的對(duì)象具有復(fù)制成本(年輕代集合的算法的一部分是復(fù)制任何存活的對(duì)象)。中期或長(zhǎng)期對(duì)象可能會(huì)被復(fù)制多次。使用 -XX 選項(xiàng)MaxTenuringThreshold 來(lái)確定復(fù)制成本。使用 -XX:MaxTenuringThreshold=0 將在年輕代集合中幸存的對(duì)象立即移動(dòng)到終身代。如果這提高了應(yīng)用程序的性能,那么長(zhǎng)期對(duì)象的復(fù)制就很重要。請(qǐng)注意,吞吐量收集器不使用 MaxTenuringThreshold 參數(shù)。

8.垃圾收集何時(shí)開(kāi)始?

在默認(rèn)垃圾收集器中,當(dāng)代已滿時(shí)(即,無(wú)法從該代進(jìn)行進(jìn)一步分配時(shí))會(huì)收集該代。吞吐量收集器也是如此。并發(fā)低暫停收集器在老年代的占用率達(dá)到指定值(默認(rèn)為 68%)時(shí)開(kāi)始收集。增量低暫停收集器在每次年輕代收集期間收集一部分老年代。集合也可以由應(yīng)用程序顯式啟動(dòng)。

9.System.gc() 做什么類型的集合?

執(zhí)行垃圾收集的顯式請(qǐng)求會(huì)執(zhí)行完整收集(年輕代和老生代)。完整的收集總是在應(yīng)用程序在收集期間暫停的情況下完成。

10.什么是并發(fā)標(biāo)記掃描 (CMS) 收集器?

Concurrent Mark Sweep (CMS) 收集器(也稱為并發(fā)低暫停收集器)收集tenured generation。它試圖通過(guò)與應(yīng)用程序線程同時(shí)進(jìn)行大部分垃圾收集工作來(lái) 最小化由于垃圾收集而導(dǎo)致的暫停。

11.為什么碎片是并發(fā)低暫停收集器的 潛在問(wèn)題?

通常并發(fā)低暫停收集器不會(huì)復(fù)制或壓縮活動(dòng)對(duì)象。垃圾收集是在不移動(dòng)活動(dòng)對(duì)象的情況下完成的。如果碎片成為問(wèn)題,請(qǐng)分配更大的堆。在 1.4.2 中,如果老年代的碎片成為一個(gè)問(wèn)題,老年代的壓縮將被完成,盡管不是同時(shí)進(jìn)行。在 1.4.1 中,如果啟用了UseCMSCompactAtFullCollection選項(xiàng),則會(huì)發(fā)生壓縮 。

-XX:+UseCMSCompactAtFullCollection

12.并發(fā)低暫停收集器的階段是什么?

收集涉及六個(gè)階段:

階段 1(初始檢查點(diǎn))涉及停止所有 Java 線程,標(biāo)記所有可從根直接訪問(wèn)的對(duì)象,并重新啟動(dòng) Java 線程。

階段 2(并發(fā)標(biāo)記)從標(biāo)記的對(duì)象開(kāi)始掃描,并傳遞標(biāo)記從根可到達(dá)的所有對(duì)象。mutator在下面 的并發(fā)階段 2、3 和 5 期間執(zhí)行,并且在這些階段期間在 CMS 生成中分配的任何對(duì)象(包括提升的對(duì)象)都會(huì)立即標(biāo)記為活動(dòng)的。

階段 3:在并發(fā)標(biāo)記階段,mutator 可能正在修改對(duì)象。自并發(fā)標(biāo)記階段開(kāi)始以來(lái)已修改的任何對(duì)象(并且在該階段隨后未掃描)都必須重新掃描。 階段 3(并發(fā)預(yù)清理)掃描已同時(shí)修改的對(duì)象。由于持續(xù)的mutator 活動(dòng),可能會(huì)多次掃描修改過(guò)的卡片。

第 4 階段(最終檢查點(diǎn))是一個(gè)停止世界的階段。隨著突變體的停止,最終的標(biāo)記是通過(guò)掃描從根可以到達(dá)的對(duì)象并掃描任何修改過(guò)的對(duì)象來(lái)完成的。請(qǐng)注意,在此階段之后,可能會(huì)有已標(biāo)記但不再存在的對(duì)象。此類對(duì)象將在當(dāng)前集合中存活,但將在下一個(gè)集合中收集。

階段 5(并發(fā)掃描)收集死對(duì)象。死對(duì)象的集合將對(duì)象的空間添加到空閑列表以供以后分配。此時(shí)可能會(huì)發(fā)生死對(duì)象的合并。請(qǐng)注意,活動(dòng)對(duì)象不會(huì)移動(dòng)。

階段 6(重置)清除數(shù)據(jù)結(jié)構(gòu),為下一次收集做準(zhǔn)備。

13.VM 是否分配大型 int 數(shù)組供自己使用?

JVM 確實(shí)分配大 int[] 的一個(gè)地方是當(dāng)它填滿 內(nèi)存的各個(gè)碎片部分以使垃圾收集器看起來(lái)完整時(shí)。例如,在 GC 之前每個(gè)線程本地分配緩沖區(qū)的未使用部分,或者在運(yùn)行 JVMPI 對(duì)象分配事件時(shí)的所有年輕代。

14.我可以看到有多少線程分配緩沖區(qū)未使用嗎?

有一個(gè)標(biāo)志, -XX:+ PrintTLAB,它將跟蹤 TLAB 上的所有操作。 特別是,它打印像

重置 TLAB:線程:0x0002d7d0 大?。?KB 未使用:76B 總碎片 0.004499

每次 TLAB 填充一個(gè) int[]。在這種情況下,未使用的尾隨 76B 將未被使用。

這是一個(gè) TLAB 已填滿并將分配一個(gè)新 TLAB 的示例。這里的垃圾量比較少。在為垃圾收集做準(zhǔn)備時(shí),可能會(huì)產(chǎn)生更多的浪費(fèi)。對(duì)于在垃圾收集之前顯示的 TLAB 輸出,例如

重置 TLAB:線程:0x0002d840 大?。?KB 未使用:7276B 總碎片 0.004580

[全 GC 10424K->591K(15688K),0.1222677 秒]

我們正在填充 8192 字節(jié) TLAB 的 7276 字節(jié)。(“總碎片”是由TLAB 引起的碎片的累積計(jì)算。)默認(rèn)情況下,在 SPARC 服務(wù)器上調(diào)整 TLAB 的大小,或者如果您使用 -XX:+ ResizeTLAB 標(biāo)志,因此如果您正在運(yùn)行,您很可能會(huì)得到大的TLAB那個(gè)JVM。請(qǐng)注意,我們不會(huì)在集合之前“浪費(fèi)”填充器的空間,因?yàn)榧蠈⒒謴?fù)填充器對(duì)象占用的空間。

15.NewRatio 的默認(rèn)值會(huì)隨著編譯器的變化而變化嗎?

在 SPARC 上,-XX:NewRatio 默認(rèn)為 -client 為 8,-server 為 2,因此年輕代與老年代的比率將為 1::8,而年輕代將是堆的 1/9 -客戶端和 1::2 或 1/3 的堆與 -server。

16.什么是并行垃圾收集器 (-XX:+UseParallelGC)?

新的并行垃圾收集器類似于默認(rèn)垃圾收集器中的年輕代收集器,但使用多個(gè)線程進(jìn)行收集。默認(rèn)情況下,在具有 N個(gè) CPU的主機(jī)上,并行垃圾收集器在收集中使用 N 個(gè)垃圾收集器線程。垃圾收集器線程的數(shù)量可以通過(guò)命令行選項(xiàng)來(lái)控制(見(jiàn)下文)。在具有單個(gè) CPU 的主機(jī)上,即使已請(qǐng)求并行垃圾收集器,也會(huì)使用默認(rèn)垃圾收集器。在具有 2 個(gè)cpu 的主機(jī)上,并行垃圾收集器的性能通常與默認(rèn)垃圾收集器一樣好,并且在具有超過(guò) 2 個(gè) cpu 的主機(jī)上可以預(yù)期減少年輕代垃圾收集器的暫停時(shí)間。

這個(gè)新的并行垃圾收集器可以通過(guò)使用命令行產(chǎn)品標(biāo)志 -XX:+UseParallelGC 來(lái)啟用??梢允褂?ParallelGCThreads 命令行選項(xiàng) (-XX:ParallelGCThreads=<desired number>) 控制垃圾收集器線程的數(shù)量。此收集器不能與并發(fā)低暫停收集器一起使用。

17.什么是并行年輕代收集器(-XX:+UseParNewGC)?

并行年輕代收集器在意圖上類似于并行垃圾收集器(-XX:+UseParallelGC),但在實(shí)現(xiàn)上有所不同。因此,以上對(duì)并行垃圾收集器 (-XX:+UseParallelGC) 的大部分描述同樣適用于并行年輕代收集器。與并行垃圾收集器 (-XX:+UseParallelGC) 不同,此并行年輕代收集器可以與收集終身代的并發(fā)低暫停收集器一起使用。

18.我應(yīng)該使用哪個(gè)并行收集器?

盡管意圖相似,但收集器在實(shí)現(xiàn)的某些細(xì)節(jié)上有所不同,這使得并行垃圾收集器更適合某些應(yīng)用程序,而并行年輕代收集器更適合其他應(yīng)用程序。兩者都應(yīng)該嘗試確定哪個(gè)可能更適合特定應(yīng)用程序。

此外,并行年輕代收集器 (-XX:+UseParNewGC) 與并發(fā)低暫停收集器集成,而并行垃圾收集器 (-XX:+UseParallelGC) 則沒(méi)有。即使不使用并發(fā)低暫停收集器,也會(huì)產(chǎn)生與此集成相關(guān)的一些成本。相反,并行垃圾收集器 (-XX:+UseParallelGC) 可以與自適應(yīng)大小 (-XX:+UseAdaptiveSizePolicy) 一起使用,而并行年輕代收集器 (-XX:+UseParNewGC) 則不能。

19.為什么并發(fā)低暫停 (CMS) 收集器的啟動(dòng)速度很慢?

使用 CMS (+XX:UseConcMarkSweepGC),您有時(shí)需要將最小和最大堆大小設(shè)置為相同的值(或至少設(shè)置一個(gè)較大的最小值),因?yàn)?CMS 有時(shí)會(huì)花時(shí)間提前增長(zhǎng)其堆。燙發(fā)一代也可能如此。使用選項(xiàng) -XX 嘗試更大的 perm 生成大?。篜ermSize =<initial size> -XX:MaxPermSize=<maximum size>。

20.什么年輕代收集器與并發(fā)低暫停收集器一起使用?

默認(rèn)情況下,低暫停收集器使用默認(rèn)的單線程年輕代復(fù)制收集器。如果您指定 +XX:UseParNewGC 將使用復(fù)制收集器的并行版本。

21.為什么低暫停收集器有時(shí)會(huì)比默認(rèn)收集器做更多的收集?

如果您沒(méi)有看到使用默認(rèn)收集器的主要收集,但看到使用并發(fā)低暫停收集器的許多主要收集,您可能會(huì)看到某種類型的碎片問(wèn)題。嘗試使用更大的堆和并發(fā)低暫停收集器。

22.垃圾收集文檔是否還有其他外部資源?

http://developer.java.sun.com/developer/technicalArticles/Programming/turbo/

23.對(duì)于并發(fā)低暫停收集器,NewRatio 的最小值是多少?

建議最小值 為4。

24.對(duì)象會(huì)直接分配到老年代嗎?

在 1.4.1 中有兩種情況,分配可能直接發(fā)生在老年代。

如果年輕代分配失敗,并且對(duì)象是一個(gè)不包含任何對(duì)象引用的大數(shù)組,則可以直接將其分配到年老代。在某些特定情況下,此策略旨在通過(guò)從老年代分配來(lái)避免收集年輕代。

有一個(gè)標(biāo)志(在 1.4.2 和更高版本中可用)l-XX: PretenureSizeThreshold =<byte size> 可以設(shè)置來(lái)限制年輕代中分配的大小。任何大于此的分配都不會(huì)在年輕代中嘗試,因此將被分配到老年代之外。

1) 的閾值大小為 64k 字。PretenureSizeThreshold 的默認(rèn)大小為 0,表示可以在年輕代中分配任何大小。

在 1.4.2 案例 1) 中,增量收集器 (-Xincgc) 的 64k 字閾值仍然有效。對(duì)于默認(rèn)收集器和并發(fā)收集器(-XX:+UseConcMarkSweepGC),閾值已更改,因此僅當(dāng)分配的大小大于整個(gè)年輕代(可用空間時(shí)它是空的)。據(jù)觀察,在某些情況下,默認(rèn)收集器和并發(fā)收集器的 1.4.1 策略僅導(dǎo)致完全收集(沒(méi)有進(jìn)行年輕代收集)。我們認(rèn)為這足以提高門檻。

25.我應(yīng)該增加客戶端虛擬機(jī)中永久代的大小嗎?

這將永遠(yuǎn)是一個(gè)判斷電話。一般來(lái)說(shuō),增加一代的大小(這不僅適用于永久代)可以減少各種問(wèn)題的發(fā)生率,但是,這可能會(huì)導(dǎo)致其他進(jìn)程過(guò)度分頁(yè)和/或垃圾收集或拋出-內(nèi)存異常。

有兩種故障模式需要考慮。

提高 MaxPermSize 時(shí),以前行為良好的程序可能會(huì)因無(wú)休止的分頁(yè)而死掉,這些程序用于垃圾收集以恢復(fù)永久代空間。對(duì)于永久代,這通常只發(fā)生在臨時(shí)字符串的大量實(shí)習(xí)中。

另一種故障模式是必須為永久代保留地址空間,這將減少堆其余部分的可用空間(最大值 -Xmx 可能會(huì)太大)。這將導(dǎo)致配置為使用所有可用空間的程序在初始化時(shí)失敗。

最近的 VM中的永久代默認(rèn)值。

發(fā)布

v1.3.1_06

v1.4.1_01

v1.4.2

客戶

永久大小

1M

4M

4M

服務(wù)器

永久大小

1M

4M

16M

客戶

最大燙發(fā)尺寸

32M

64M

64M

服務(wù)器

最大燙發(fā)尺寸

64M

64M

64M

我應(yīng)該匯集對(duì)象來(lái)幫助 GC 嗎?我應(yīng)該定期調(diào)用 System.gc() 嗎?

這些問(wèn)題的答案是否定的!

池化對(duì)象將導(dǎo)致它們的壽命超過(guò)必要的時(shí)間。我們強(qiáng)烈建議不要使用對(duì)象池。

不要調(diào)用 System.gc()。系統(tǒng)將確定何時(shí)適合進(jìn)行垃圾收集,并且通常具有更好地啟動(dòng)垃圾收集所需的信息。如果您在垃圾收集方面遇到問(wèn)題(暫停時(shí)間或頻率),請(qǐng)考慮調(diào)整代的大小。

什么決定了何時(shí)刷新軟引用的對(duì)象?

從 J2SE 1.3.1 中的 Java HotSpot VM 實(shí)現(xiàn)開(kāi)始,軟可訪問(wèn)對(duì)象將在最后一次被引用后保持活動(dòng)一段時(shí)間。默認(rèn)值是堆中每兆字節(jié)的生命周期一秒。該值可以使用 -XX:SoftRefLRUPolicyMSPerMB 標(biāo)志進(jìn)行調(diào)整,該標(biāo)志接受表示每 MB 可用內(nèi)存毫秒數(shù)的整數(shù)值。例如,要將值從 1 秒更改為 2.5 秒,請(qǐng)使用以下標(biāo)志:

-XX:SoftRefLRUPolicyMSPerMB =2500

Java HotSpot Server VM 使用最大可能的堆大?。ㄓ?-Xmx 選項(xiàng)設(shè)置)來(lái)計(jì)算剩余的可用空間。

Java HotSpot Client VM 使用當(dāng)前堆大小來(lái)計(jì)算可用空間。

這意味著服務(wù)器 VM 的總體趨勢(shì)是增加堆而不是刷新軟引用,因此 -Xmx 對(duì)軟引用何時(shí)被垃圾收集具有顯著影響。

另一方面,客戶端虛擬機(jī)將更傾向于刷新軟引用而不是增加堆。

上述行為適用于 Java HotSpot VM 的當(dāng)前(J2SE 1.3.1 和 J2SE 1.4.x)版本。 請(qǐng)注意,不保證 -XX:SoftRefLRUPolicyMSPerMB 標(biāo)志存在于任何給定版本中。

在 1.3.1 版之前,Java HotSpot VM 在找到軟引用時(shí)會(huì)清除它們。

當(dāng)我打開(kāi) -verbose:gc 時(shí),我得到了很多完整的垃圾回收( GC ) 。GC 定期進(jìn)行。我的應(yīng)用程序從不調(diào)用 System.gc。我已經(jīng)調(diào)整了堆,它沒(méi)有任何區(qū)別,這是怎么回事?

如果您使用的是 RMI(遠(yuǎn)程方法調(diào)用),那么您可能會(huì)遇到分布式垃圾回收 (GC)。此外,一些應(yīng)用程序正在添加顯式 GC 的想法,認(rèn)為這將使他們的應(yīng)用程序更快。幸運(yùn)的是,您可以使用 1.3 和 1.4 版本中提供的選項(xiàng)禁用此功能。嘗試 -XX:+ DisableExplicitGC 和 -verbose:gc 看看這是否有幫助。

并發(fā)低暫停收集器似乎大部分時(shí)間都在進(jìn)行完整收集。如何加快并發(fā)收集?

并發(fā)收集通常無(wú)法加速,但可以更早地啟動(dòng)。

當(dāng)老年代中分配的空間百分比超過(guò)閾值時(shí),并發(fā)收集開(kāi)始運(yùn)行。此閾值是根據(jù)并發(fā)收集器的一般經(jīng)驗(yàn)計(jì)算得出的。如果正在發(fā)生完整收集,則可能需要更早地啟動(dòng)并發(fā)收集。命令行標(biāo)志 CMSInitiatingOccupancyFraction 可用于設(shè)置開(kāi)始收集的級(jí)別。其默認(rèn)值約為 68%。調(diào)整值的命令行是

-XX:CMSInitiatingOccupancyFraction=<百分比>

并發(fā)收集器還會(huì)統(tǒng)計(jì)應(yīng)用程序進(jìn)入老年代的提升率,并根據(jù)提升率和老年代的可用空間來(lái)預(yù)測(cè)何時(shí)開(kāi)始并發(fā)收集。盡管 CMSInitiatingOccupancyFraction 的使用必須保守以避免在應(yīng)用程序的生命周期內(nèi)完全收集,但基于預(yù)期提升的并發(fā)收集的啟動(dòng)適應(yīng)應(yīng)用程序不斷變化的需求。用于計(jì)算提升率的統(tǒng)計(jì)信息基于最近的并發(fā)收集。在至少一個(gè)并發(fā)收集完成之前不會(huì)計(jì)算提升率,因此至少必須啟動(dòng)第一個(gè)并發(fā)收集,因?yàn)檎加寐室堰_(dá)到 CMSInitiatingOccupancyFraction 。將 CMSInitiatingOccupancyFraction 設(shè)置為 100 不會(huì)導(dǎo)致僅使用預(yù)期提升來(lái)啟動(dòng)并發(fā)收集,而是只會(huì)導(dǎo)致非并發(fā)收集發(fā)生,因?yàn)椴l(fā)收集直到為時(shí)已晚才會(huì)啟動(dòng)。消除使用預(yù)期提升來(lái)啟動(dòng)并發(fā)收集集UseCMSInitiatingOccupancyOnly 為真。

-XX:+UseCMSInitiatingOccupancyOnly

有時(shí),當(dāng)一個(gè)完整的收集開(kāi)始時(shí),并發(fā)低暫停收集器即將完成并發(fā)收集的最后一部分。完整的集合看起來(lái)就像它再次完成了整個(gè)集合。這會(huì)發(fā)生嗎?

默認(rèn)情況下,完整集合使用與并發(fā)集合不同的集合算法(壓縮)。因此,正在進(jìn)行的并發(fā)收集所做的所有工作都會(huì)丟失。可以對(duì)此進(jìn)行調(diào)整,以便完整收集將完成并發(fā)收集,盡管不是同時(shí)進(jìn)行。一個(gè)完整的集合通常會(huì)進(jìn)行壓縮,因?yàn)闊o(wú)法同時(shí)完成它的集合通常是碎片問(wèn)題的標(biāo)志。在許多情況下,需要進(jìn)行壓縮,但可以通過(guò)將 CMSFullGCsBeforeCompaction的值設(shè)置為 1 來(lái)延遲 1 次完整收集 。

-XX:CMSFullGCsBeforeCompaction=1

當(dāng)一個(gè)完整的收集開(kāi)始時(shí)使用這個(gè)值,它將完成正在進(jìn)行的并發(fā)收集。如果在正常并發(fā)收集完成之前發(fā)生另一個(gè)完整收集,則將完成壓縮。

使用并發(fā)低暫停收集器,我如何知道還剩下多少浮動(dòng)垃圾?

因?yàn)閼?yīng)用程序線程和 GC 線程同時(shí)運(yùn)行,所以在收集開(kāi)始時(shí)處于活動(dòng)狀態(tài)且 GC 線程已標(biāo)記為活動(dòng)的對(duì)象可能會(huì)在收集結(jié)束時(shí)死亡。這樣的對(duì)象被稱為浮動(dòng)垃圾。如果在并發(fā)收集之后立即發(fā)生完全壓縮收集,則可以推斷出浮動(dòng)垃圾的數(shù)量。堆大小的任何減少都是由于浮動(dòng)垃圾。

并行收集器似乎使用與機(jī)器上的處理器一樣多的垃圾收集器 (GC) 線程。如何請(qǐng)求更多或更少的 GC 線程?

GC線程數(shù)由選項(xiàng)控制

-XX:ParallelGCThreads=<number_of_GC_threads>

為什么并發(fā)低暫停收集器會(huì)出現(xiàn)碎片?

并發(fā)低暫停收集器通常不會(huì)在垃圾收集期間移動(dòng)對(duì)象。當(dāng)活動(dòng)對(duì)象散布在收集結(jié)果留下的可用空間時(shí),就會(huì)發(fā)生碎片。例外情況是發(fā)生非并發(fā)的完整收集時(shí)。在后一種情況下,應(yīng)用程序在收集期間停止,活動(dòng)對(duì)象被壓縮到一代的一端,所有空閑空間都駐留在一個(gè)連續(xù)的塊中。

吞吐量收集器應(yīng)該使用哪些選項(xiàng)?

使用的正確選項(xiàng)取決于您的應(yīng)用程序。以下是一些典型用途,但這些都不是最適合您的應(yīng)用程序的。

服務(wù)器應(yīng)用程序單獨(dú)運(yùn)行在具有 4GB 物理內(nèi)存的大型多處理器服務(wù)器上。

#java -server -XX:+AggressiveHeap

兩個(gè)應(yīng)用程序?qū)嵗诰哂?4GB 物理內(nèi)存的大型多處理器服務(wù)器上運(yùn)行。每個(gè) java 應(yīng)用程序?qū)嵗纪ㄟ^(guò)最大和最小堆大小的顯式規(guī)范分配總系統(tǒng)內(nèi)存的一部分。

#java -server -XX:+AggressiveHeap -Xms1024m -Xmx1024m

不使用 AggressiveHeap 標(biāo)志的示例

#java -server -XX:+UseParallelGC -XX:ParallelGCThreads=4 -Xms1024m -Xmx1024m

并發(fā)低暫停收集器應(yīng)該使用哪些選項(xiàng)?

使用的正確選項(xiàng)取決于您的應(yīng)用程序。以下是一些典型用途,但這些都不是最適合您的應(yīng)用程序的。

在具有 1 GB 物理內(nèi)存的處理器系統(tǒng)上運(yùn)行的服務(wù)器應(yīng)用程序。

#java -Xmx512m -Xms512m -XX:MaxNewSize=24m -XX:NewSize=24m -XX:+UseConcMarkSweepGC

在具有 1GB 物理內(nèi)存的多處理器系統(tǒng)上運(yùn)行的服務(wù)器應(yīng)用程序 - 使用并行次要收集選項(xiàng)。

#java -Xmx512m -Xms512m -XX:MaxNewSize=24m -XX:NewSize=24m -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:+UseConcMarkSweepGC

并發(fā)低暫停收集器的默認(rèn)設(shè)置是什么?

并發(fā)低暫停收集器的默認(rèn)堆大小與默認(rèn)收集器相同。其他參數(shù)的設(shè)置如下所述。這些設(shè)置已被證明適用于具有大部分壽命很短的數(shù)據(jù)以及一些壽命很長(zhǎng)的數(shù)據(jù)的應(yīng)用程序。一些選項(xiàng)需要用尖括號(hào) (<>) 括起來(lái)的計(jì)算,其中兩個(gè)取決于機(jī)器上的 CPU 數(shù)量 (#cpus。)

# 啟用并發(fā)低暫停收集器

-XX:+UseConcMarkSweepGC

# 使用并行線程

-XX:+UseParNewGC

-XX:ParallelGCThreads=<#cpus < 8 ? #cpus : 3 + ((5 * #cpus) / 8) >

-XX:+CMSParallelRemarkEnabled

# 為短暫的停頓調(diào)整年輕代的大小

-XX:NewSize=4m

-XX:MaxNewSize=< 4m * ParallelGCThreads >

# 提升所有活躍的年輕代對(duì)象

-XX: MaxTenuringThreshold = 0

-XX:幸存者比率=1024

還建議使用比默認(rèn)收集器使用的堆大小大 20-30% 的堆大小。

增量低暫停收集器應(yīng)該使用哪些選項(xiàng)?

使用的正確選項(xiàng)取決于您的應(yīng)用程序。以下是一些典型用途,但這些都不是最適合您的應(yīng)用程序的。

具有 1GB 物理內(nèi)存的服務(wù)器應(yīng)用程序。

#java -server -Xincgc -XX:NewSize=64m -XX:MaxNewSize=64m -Xms512m -Xmx512m

如果發(fā)生完全收集,則上面的應(yīng)用程序表明沒(méi)有足夠快地增量收集終身代。

#java -server -Xincgc -XX:NewSize=24m -XX:MaxNewSize=24m -Xms512m -Xmx512m

草稿版本:2003 年 2 月 6 日

版權(quán)所有 ? 2003 Sun Microsystems, Inc.。保留所有權(quán)利。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Java 虛擬機(jī)有自己完善的硬件架構(gòu), 如處理器、堆棧、寄存器等,還具有相應(yīng)的指令系統(tǒng)。JVM 屏蔽了與具體操作系...
    尹小凱閱讀 1,759評(píng)論 0 10
  • 垃圾收集器在對(duì)堆進(jìn)行回收前,需要先確定這些對(duì)象中哪些還“存活”著,哪些已經(jīng)“死去”(也就是不被任何引用類型所引用)...
    滿天星愛(ài)我閱讀 586評(píng)論 0 6
  • 走進(jìn)JVM JVM概述 JVM(Java Virtual Machine)是一種用于計(jì)算設(shè)備的規(guī)范,它是一個(gè)虛構(gòu)出...
    關(guān)阿貍閱讀 456評(píng)論 0 0
  • 1、范圍:要回收哪些區(qū)域 在JVM五種內(nèi)存模型中,有三個(gè)是不需要進(jìn)行垃圾回收的:程序計(jì)數(shù)器、JVM棧、本地方法棧。...
    冰河winner閱讀 596評(píng)論 0 2
  • 第一部分:自動(dòng)內(nèi)存管理 總圖: 部分名詞解釋: slot(槽):指棧中存放局部變量的容器。double、long占...
    月明星稀_8184閱讀 814評(píng)論 0 0

友情鏈接更多精彩內(nèi)容