2015-06-08 53 views
2

我創建了測試應用程序(每20ms運行一次Sheduler,有讀/寫數據庫)並將其部署到兩臺不同PC上的Glassfish服務器上。 Glassfish(兩者都有最新的JAVA版本)服務器具有以下標誌:-XX:+ DisableExplicitGC,XX:MaxGCPauseMillis = 200,-Xmx512m,-Xms512m,-XX:+ UseCompressedClassPointers -XX :+ UseCompressedOops -XX:+ UseG1GC,-server ...JVM與同一標誌的功能非常不同

第一臺PC有8GB RAM,i5 CPU(2.5 GHz)和WIN 8.1 64bit操作系統。

這是第一臺PC的GC日誌的圖形顯示(30小時後): enter image description here

正如你可以看到GC Peformance大約是12000 MB/s的吞吐量是99,93%,次要GC暫停大約20ms長,每30秒發生一次。在這個時候沒有主要的GC(但它發生在8小時後)。在前30個小時,老一代從90 MB增加到160 MB。

第二臺PC有1GB內存,Athlon 64 X2(雙核)CPU和WIN XP 32bit。這是第二個PC的GC日誌的圖形顯示(30小時後): enter image description here

正如你可以看到GC Peformance大約是4000 MB/s的吞吐量是99,91%,次要GC暫停大約100毫秒長並且它們每50秒發生一次。在這個時候沒有主要的GC(4天后仍然沒有發生)。在前30個小時,老一代從70 MB增加到75 MB。

這裏我的問題是:爲什麼在第二種情況下比第一種情況下的老一代的升級要小?這意味着主要GC在第一種情況下在40小時後被觸發時,相當一段時間(可能永遠不會)觸發主要GC。應用程序在這兩種情況下都做了相同的事情,所以我不明白爲什麼JVM在相同標誌下運行的方式有很大不同。我不知道在第一種情況下有什麼好處(如果這意味着在第二種情況下主要的GC必須發生,那麼主要的GC將不會發生)。如果在兩臺服務器上的應用程序以相同的速度執行(每20ms向DB寫入一次,然後從相同的數據塊讀取一部分數據),從倖存空間升級到舊一代有什麼好處。第二種情況下的次要GC比第一種情況(30秒)更少(50秒)。我認爲,比起更好的PC會有更好的結果,但現在我甚至不知道哪一個更好......只有第一種情況的主要優點是GC性能更高,因此小GC更快完成。謝謝大家澄清爲什麼它是這樣完成的。

+0

每個Java的確切版本是什麼? –

+1

兩者都是最新版本的JAVA(8u45),首先是64bit,第二個是32bit。 – user4341206

+4

將'-XX:+ PrintFlagsFinal'添加爲最後的VM標誌,捕獲輸出並運行diff。 32位和64位虛擬機最有可能表現得非常不同,因爲前者可能會被歸類爲客戶端級機器。線程數也可能有所不同。 – the8472

回答

3

我希望優於PC將有更好的結果,但現在我甚至不知道哪一個更好?

更好的是主觀的。取決於您是否需要吞吐量(GCing花費的CPU週期的一小部分),可持續分配率,低暫停時間或低佔用空間。通常在這些目標之間進行權衡。

G1GC是一種複雜的自我調整的野獸,在不同的環境下表現不同。所以除非你想避免實際存在問題的行爲,問題在哪裏?它只是做不同的工作。

正如評論中所述,如果您只是想滿足您的好奇心,您可以通過在選項中附加-XX:+PrintFlagsFinal來比較VM標誌並運行差異。它們可能很不相同,因爲32位和64位系統得到不同的默認值。

+0

我會盡快使用-XX:+ PrintFlagsFinal來比較標誌,這樣我就可以訪問兩臺PC。我有一個「愚蠢」的問題:如果我正在運行glassfish服務器(可能是在啓動時的域登錄或其他地方)顯示這些標誌?我只是好奇,爲什麼這樣的差異,我一直認爲比較少的主要(或全部)GC比其中更多的人更好... – user4341206

+0

通常這是打印到標準輸出。我不知道glassfish是做什麼的,也許它會將所有內容重定向到日誌文件。但你不必運行glassfish來打印虛擬機選項,你可以簡單地使用相同的選項,並從'cmd'手動調用它。 – the8472

+0

謝謝。標誌有很多不同之處(在64位版本中,其中更多的設置爲true或設置爲更高的值),有些在32版本中缺失。 – user4341206