2013-02-19 17 views
9

給出一個Java的內存配置,如以下Java堆行爲

-Xmx2048m -Xms512m 

什麼是虛擬機時,內存使用率增加過去512米的行爲?它是否有一個特定的算法?即。它是否直接達到最大值,是否加倍,是以增量進行還是僅僅因爲需要內存而進行分配?它是多麼昂貴的一項操作?

我在甲骨文/ Sun JVM尋找具體而言,1.6版。我認爲這被記錄在Oracle網站的某處,但我無法找到它。

+0

它絕對不會直接進入最大值。 – 2013-02-19 23:27:41

+0

您正在定義最小值+最大值。它至少有512MB,但是有2048mb的上限。 – adrian 2013-02-19 23:28:48

+0

根據我的理解,最小內存值是在JVM啓動時分配的 - 因此,在啓動時,它會從主機操作系統消耗512m以供其自己使用。我不明白的是什麼時候它需要超過512米,需要多少費用,以及它如何使用它?例如 - JVM需要750MB - 它會消耗750MB精確,還是增長到1024MB?或者遵循其他一些行爲? – Ren 2013-02-19 23:30:37

回答

6

這是垃圾收集器的工作,決定調整是必要時,所以它是由GC參數確定「MinFreeHeapRatio。」如果GC需要更多的空間,它將增長到可以使用該值指定的堆的百分比。

一個現代化的平臺的典型值是40ish,所以如果你開始在512MB,並有免費少於40%,這意味着你超過〜308MB,這將增加至40%是免費的一次。所以說收集後仍然有400MB的實時對象,你的堆將會增加到667MB。 (是的,它被命名的比例,但期望%值作爲論點...搜索我!)

注意這是有點不精確,垃圾回收器是「世代」,實際上可以調整個別世代,但它也有強迫世代之間的比例大小,如果您的對象大致按照它估計的方式分佈在長壽命和短壽命之間,那麼它在信封背面工作得非常好。

這適用於默認使用Java 6.如果您使用自定義的垃圾收集器的配置可能會有所不同。您可以在這裏閱讀:http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html#generation_sizing.total_heap

(操作類型的「費用」取決於操作系統和其他操作如果系統加載關閉,操作系統必須做一些交換操作一個連續的內存塊,然後它可能是非常昂貴的!)

+0

正是我需要的!謝謝。 – Ren 2013-02-20 00:06:02

2

使用-verbose:gc和/或-XX:+PrintGCDetails選項應該給你許多更好的細節。

這裏是與-verbose:gc選項輸出例如開啓:

[GC 325407K->83000K(776768K), 0.2300771 secs] 
[GC 325816K->83372K(776768K), 0.2454258 secs] 
[Full GC 267628K->83769K(776768K), 1.8479984 secs] 

從官方document採取了上述的解釋:

這裏,我們看到後面跟着一個大兩個小集合採集。 數字之前和箭頭之後(例如,325407K->83000K從 第一行)表示活動對象的前垃圾收集後的組合大小和 ,分別。未成年人集合後, 大小包括某些對象都是垃圾(不再活着),但 無法回收。這些對象包含在終身 一代,或從持久或永久世代引用。

括號中的下一個號碼(例如,(從第一 線776768K)再次)是堆的承諾尺寸:用於java對象可用 空間,而不從操作 系統要求更多的內存量。請注意,此數字不包含倖存者 中的一個空格,因爲在任何給定時間只能使用一個空格,並且 也不包含永久生成,該永久生成保存虛擬機使用的元數據。

線上的最後一項(例如,0.2300771 secs)表示用於執行收集的時間 ;在這種情況下大約四分之一秒 。

第三行主要集合的格式類似。

以這種方式運行應用程序以及更新最小和最大堆大小可以很好地洞察虛擬機的堆分配和垃圾收集模式。

0

需要注意的是,初始化時的JVM虛擬地保留最大地址空間但不分配物理內存。通常JVM會將空間分配給Old和Young一代。年輕一代有着中間空間。所引用的新對象包含在年輕一代中。

當填充了中間空間時,調用GC將引用對象移動到年輕代中的稱爲Survivor Space的Intermidatory空間之一。 GC可能通過保存線程的狀態算法或算法來遵循「停止世界」,以便進程保持運行(?)。

當Survivor空間填滿JVM時調用完整的GC。