我正在使用JVM進行科學應用。我的過程中的第一步是將大量數據加載到很少的double[]
數組(大圖中每個節點的48個元素的數組)。很久以前,我發現是否有足夠的內存來加載它們,Java漸近地減速,jvisualvm告訴我這是因爲幾乎所有的CPU時間都花費在垃圾回收中:加載數據時達到飽和點;我如何控制Java GC代?
第一分鐘左右是好的:「使用的堆」(右圖)跳向上和向下,因爲它生長,因爲有些對象是臨時的(我在斯卡拉寫這個),有些對象是永久性的。然而,在那之後,數據加載會停下來,因爲垃圾收集器顯然是一遍又一遍地檢查同一個對象(左圖)。它一定會期待它們超出範圍,但我將它們保留在範圍之內,因爲我想將它們用於我的分析。
我知道垃圾收集器根據它們的生存可能性將對象放在不同的世代中。第一代包含最近創建並很快可能死亡的對象;後代人越來越有可能長壽。如果我的對象在第一代出現錯誤,是否有任何方法告訴垃圾回收者他們應該在後一代?我知道我會保持他們 - 我怎麼能告訴垃圾收集器?
儘管我希望這些物體處於更持久的一代,但PermGen會過於沉重:經過數十分鐘的處理後,它們將最終死亡。 (我想在Hadoop的減速,這可能這一個沒有新的JVM後,在不同的塊數據的工作,用這個。)
注:我使用的是Sun的HotSpot VM:
% java -version
java version "1.6.0_45"
Java(TM) SE Runtime Environment (build 1.6.0_45-b06)
Java HotSpot(TM) 64-Bit Server VM (build 20.45-b01, mixed mode)
校正(到以前的編輯):更改-Xmx
確實變化的飽和點,但顯然Java的,如果它是在-jar
爭吵後通過忽略-Xmx
命令行參數。也就是說,不要
java -Xmx2048 -jar MyJarFile.jar
而不是
java -jar MyJarFile.jar -Xmx2048
正因爲如此,我被錯誤地診斷相對於最大堆行爲和所有指向-Xmx
標誌的答案是有效的。
我描述的飽和點發生在「堆大小」(右圖上的橙色)達到所選-Xmx
限制時,「堆大小」始終是「使用堆」的1.6倍(右圖中的藍色)除非你用-XX:NewRatio
或-XX:OldSize
明確設置「舊」代的大小。這些也需要在-jar
的論點之前,並且它們提供了很多控制。
難道你不能重新使用這些對象嗎? – exussum
「重新使用對象」?你是什麼意思?我將它們加載到內存中,對它們進行分析。它們代表不同的數據。 –
它們可能代表不同的數據,但它們可能是同一個對象。 a = 12和b = 1534545是不同的,但如果我沒有在同一時間使用它們,我可以重新使用一個而不是創建一個「新」b並在gc上調用 – exussum