許多 java 虛擬機提供了選項來控制 Java 堆的大小和增長。本文討論了如何正確設置最小值(ms)和最大值(mx)的堆大小。最小值參數是就是堆的起始大小,因此合理地設置它以及最大值參數,可能對您的 Java 應用會產生深遠的影響。
mx 參數
在大多數情況下,假如您認為堆對于 Java 應用程序太小,就應該設置 mx 參數。通過在 Java 命令行上監視使用 verbosegc 參數運行的 JVM 的輸出,您可以確定垃圾收集是否過于頻繁。假如垃圾收集過于頻繁,則請嘗試增大堆的大小。
一般來說,假如應用程序不斷出現內存不足錯誤,則我們建議您增大 mx 參數。這些錯誤可能是由于 Java 堆中可用空間不足而引起。
盡管設置堆大小沒有規則可循,但下列原則可能會有所幫助:
不要使堆的增長超過系統的物理內存。換句話說,決不要將 mx 堆大小設置為大于 [(物理內存) - (操作系統和應用程序的工作區大小)]。另外,假如您運行多個 JVM,所有堆的大小總和應小于上述計算值。
假如應用程序需要的堆大于總物理內存的一半,則請設置 mx 參數。在 IBM Developer Kit for Windows,Java Technology Edition, 版本 1.1.8 中,mx 參數的默認值是總物理內存大小的一半。
假如您的應用程序經常依靠于終止函數 (finalizer) 的操作,則需要減小 mx 設置的大小。(注:我們建議您避免這種代碼設計。)
在 IBM Developer Kit for Windows,Java Technology Edition 中對堆增長有更好的支持對于 Java 服務器應用程序,假如您發現沒有達到最優性能,我們建議您檢查堆的大小。IBM 通過智能地增大堆解決了這一普遍存在的 Java 問題。這種技術在 IBM Developer Kit for Windows,Java Technology Edition,1.1.7 版本中首次出現,并在 IBM Developer Kit for Windows and OS/2 Warp,Java Technology Edition,1.1.8 版本中得到增強。有了這些 JVM,用戶幾乎不需要設置堆大小;與智能增長搭配的初始默認值一般就足夠了。
可能的負面影響
增大堆大小可以提高吞吐量,但會增加停頓時間。這是因為搜集大型的堆可能需要幾秒鐘的時間,但垃圾收集次數會減少。盡管這種偶然的響應時間變長對于直接通過 LAN 與服務器連接的客戶機至關重要,但以響應時間的變長來換取吞吐量的增加是值得的。堆大小是一個體系結構問題,它取決于應用程序的用途。在 IBM Developer Kit for Windows and OS/2 Warp,Java Technology Edition,1.1.8 版本中,垃圾收集和堆增長的治理都是基于活動對象,因此停頓時間對性能的影響比在 1.1.7 版本中更小。
始終追求最好
查找最佳的堆大小可能需要對應用程序、 Java 實現和操作系統作一些試驗。確定具體應用程序的最佳堆大小范圍的一種方法是將 mx 設置得非常大,然后用 verbosegc 選項運行應用程序。這將產生有關堆使用情況的輸出,您可以分析這個輸出,以便對堆大小作出明智的決策。
另一種方法需要完成更多的工作,但它使系統維護更輕易;這種方法就是確定服務器上的工作單元,即服務器完成工作的一個完整周期。例如,在批處理系統中,一個工作單元是一批請求。在更為典型的客戶機/服務器信息檢索周期中,工作單元可能是典型客戶隨其登錄/退出序列一同提交的一系列請求。過程如下:
代碼 System.gc() 調用工作單元
關閉異步垃圾收集和類垃圾收集(在命令行使用 -noasyncgc -noclassgc)
使用一個合成的驅動程序,使服務器反復執行此工作單元
采用電子表格分析 verbosegc 輸出,以確定完成平均的工作單元所需的堆大小
將這個堆大小乘以工作單元數(例如,在指定時間內希望服務器處理的用戶數或批處理數),并加上應用程序所需的基本堆大小,當然還有不很聞名的"虛構因子"
所生成的數字就是 mx 設置。這種方法需要完成更多的工作,但是,當服務器的實際負載改變時,堆大小隨時可以調整。
ms 參數
ms 參數更為簡單。假如您擔心內存利用率和擴展的開銷,則請將 ms 值設為 mx 的值。否則,就不要設置 ms。請注重,在 IBM Developer Kit for Windows and OS/2 Warp,Java Technology Edition,1.1.8 版本中,堆的大小既可以減小,也可以增大。因此,假如 ms 被設為某一值,堆則不能減小到該值以下。
我們的經驗是最好的證實
一個客戶最近所碰到的情況為我們提供了一個很好的例子,它說明 ms 和 mx 的不當設置可能導致哪些問題。該客戶的系統是通過高速 SP 基架連接的一個多節點網絡。每個節點包含 4 個 CPU,2 GB RAM。每個節點上運行 10 個 JVM。每個 JVM 都有其自己的設置,其中有個 JVM 將 ms 設為 32MB,將 mx 設為 256MB。
在啟動后幾分鐘,系統停止運行,吞吐量幾乎為零。在分析了 verbosegc 輸出之后,我們調整了堆大小,將 ms 和 mx 設為 300MB。原來每個節點不能支持超過 20 個用戶,這次更改后,現在可以輕松地支持 125 個用戶。ms 很低的初始值會導致過多的垃圾收集和緩慢的堆增長,從而導致性能嚴重下降。
新聞熱點
疑難解答