2016-09-15 132 views
2

答:如果我執行一個巨大的模擬程序-Xmx100000m(〜100GB),我看到堆中有一些尖峯(〜30GB)。這種尖峯增加了堆的大小,並減少了其他程序可以使用的內存。我想將堆大小限制爲在沒有內存異常的情況下運行程序所需的大小。最大堆大小xmx如何影響Java中的內存分配/使用堆?

enter image description here

B.如果我執行與-Xmx10000(10GB〜)我能夠限制使用的堆大小(〜7 GB)我的模擬程序。總堆大小也是如此(當然)。在VisualVM數據中顯示的程序的第一階段(大約16分鐘),我沒有發現內存不足的情況。

enter image description here

我天真地預計,如果我增加XMX從10GB(B)到100GB(A),所使用的堆會維持不變和Java的只會爲了避免出使用更多的內存內存異常。但是,這種行爲似乎有所不同。我猜Java爲了提高性能而以這種方式工作。

對A中大量使用堆的解釋可能是如果xmx較大時散列映射的增長行爲是不同的? xmx對負載因數有影響嗎?

在程序中存在很多微型尖峯的階段(例如參見B的12:06)而不是幾個大的(A)處理一些java流。流處理的內存分配是否會自動適應xmx值? (還有一些內存可用於在B 12:06時減少微型尖峯)

如果不是,那麼在A中使用較大的堆的原因是什麼?

如何可能告訴Java如果可能(如在B的曲線中)那樣保持已使用的堆低,但是如果可能發生內存不足異常(允許暫時切換到A)則需要更多的內存。這可以通過調整一些垃圾收集屬性來完成嗎?

編輯

如前所述由下面的答案,輪廓可以通過垃圾收集參數來改變。應用-Xmx100000m -XX:MaxGCPauseMillis = 1000調整A中的配置文件以消耗更少的內存(使用約20 GB)和更多時間(約22分鐘)。

enter image description here

+0

我認爲這與垃圾收集算法有關。每當GC發現有足夠的空間可用時,它不會釋放堆空間(以A爲例)。但是,當GC發現該空間不足時,它會執行垃圾收集程序並以常規和短時間間隔(情況B)釋放空間。 – KayV

回答

2

我想堆大小限制,實際上是要求無記憶的異常運行程序的大小。

你其實不願意這樣做,因爲,因爲只有提供等量的應用高峯足跡意味着當應用程序是附近最大的每一個分配將觸發垃圾收集它會使你的程序非常緩慢。

我猜Java爲了提高性能而以這種方式工作。

確實。

JVM有幾個目標,按降序排列:

  • 暫停時間(潛伏期)
  • 分配吞吐量
  • 足跡

如果要優先於其他目標的足跡你必須放鬆其他的。