主要垃圾回收過多:添加堆空間還是添加另一個 VM?
我們尚未遇到任何應用程序錯誤,但我們的監控工具表明我們的應用程序正在其資源限制下執行。我們應該先添加更多堆還是添加額外的虛擬機?
我們在託管集群中的 WebLogic/JRockit 上執行了一個應用程序。
我們有 AppDynamics 監控這個應用程序,它顯示主要垃圾收集頻繁發生(平均每 1-2 分鐘一次!!!)。當一個主要的垃圾收集執行時,它確實會回收空間,並且堆使用的較低範圍相當低,即使系統已經執行了一段時間(幾週/幾個月)。此外,我們針對生產執行了 AppDynamics 集合洩漏檢測,它沒有發現任何洩漏。(我們無法執行自定義監控,因為 JRockit 不支持它。)但總的來說,似乎沒有重大洩漏,只是系統需要比目前更多的資源。
我們有兩個非生產環境也執行這個應用程序,減少了資源和負載(開發和測試)。測試環境有 2/3 的 VM 數量和每個 VM 的 1/2 堆。我們針對這個環境執行了一些負載測試,但結果並不是很有幫助。雖然我們可以使用自動化腳本重新創建使用者數量,但我們的測試環境中的數據非常不同——查詢返回的數據要少幾個數量級,等等。(創建更好的負載測試環境當然在 ToDo 列表中,但不太可能由於官僚主義的原因,實際上很快就會發生。)即使我們可以投入一切,測試環境也沒有出汗。
兩個選項,A)添加更多堆。看起來這肯定會有所幫助,但完成這項工作需要大量文書工作(需要向物理伺服器添加更多記憶體,這意味著伺服器重啟涉及許多其他應用程序等)。另外,我不知道要添加多少記憶體,我們不能只是“在產品中測試”。B)為此應用程序添加另一個(或兩個)VM。這將相當容易,我們在另一台物理伺服器上有空間,所以我們可以很快完成它。但我不確定它會不會有多大幫助,如果它沒有幫助,那麼稍後再回到選項 A 會更加困難。
具體問題:1)上述選項中的任何一個明顯更好(為什麼)?2)如果兩者都不是明顯更好,我會做哪些測試等來決定哪個更好?3) 我應該如何決定和證明要添加多少資源(堆或虛擬機)?(如果它涉及我們已經可用的工具,則在這裡加分。)
更新:
- 一個集群中有 3 個 JVM,每個 JVM 都在一個單獨的 VM 上。
- 它們位於 Apache 負載平衡器後面,每台伺服器的負載大致相等。
- 每個 JVM 有 1 GB 堆。
- 沒有 FMW。
我們最終都做了(將更多的堆空間從 1GB 添加到 1.5GB,並將更多的託管節點從 3 個節點添加到 5 個)。
堆在添加新節點前大約一小時增加了,它本身就足以顯著減少垃圾收集的數量和垃圾收集所花費的時間。
添加更多節點只會帶來很小的改進,但很難確定它是否真的沒有太大幫助,或者在增加堆後是否沒有太大的改進空間。
假設應用程序已被徹底分析並且不存在記憶體洩漏(似乎是這種情況),您必須假設在堆中創建的對像是由於應用程序的正常活動造成的。
避免程式碼優化,和/或根據正在創建的對象的大小和生命週期(這又取決於您使用的特定 JVM)對記憶體堆進行更精細的調整,除了添加更多內容之外,沒有太大的改進空間託管節點到您的域。
這可以使用每個 WebLogic 安裝中已經存在的工具(即 WLST)輕鬆實現。
如何使用 WLST 將受管節點及其各自的節點管理器創建到現有集群中已有詳細記錄。