簡體   English   中英

64位JVM限制為300GB內存?

[英]64-bit JVM limited to 300GB of memory?

我試圖在集群計算環境(運行CentOS版本6.2 Final的IBM LSF)上運行Java應用程序,它可以為我提供高達1TB的RAM空間。

我可以創建一個具有高達300GB最大內存(Xmx)的JVM,雖然我需要更多內容(如果需要,我可以提供詳細信息)。

但是,使用Xmx選項創建具有超過300GB最大內存的JVM似乎是不可能的。 更具體地說,我收到了經典的錯誤消息:

VM初始化期間發生錯誤。

無法為對象堆保留足夠的空間。

我的(64位)JVM的詳細信息如下:

OpenJDK運行時環境(IcedTea6 1.10.6)(rhel-1.43.1.10.6.el6_2-x86_64)

OpenJDK 64位服務器VM(內置20.0-b11,混合模式)

我也嘗試過使用Java 7 64位JVM,但我遇到了完全相同的問題。

此外,我嘗試創建一個JVM來運行HelloWorld.jar,但是如果你要求超過-Xmx300G,JVM創建仍然會失敗,所以我認為它與特定應用程序沒有任何關系。


有誰知道為什么我不能創建超過300G的最大內存的JVM?

任何人都可以建議解決方案/解決方法嗎?

我可以想到幾個可能的解釋:

  • 您系統上的其他應用程序使用了大量內存,目前還沒有300Gb 可用

  • 每個進程的內存大小可能存在資源限制。 您可以使用ulimit進行檢查。 (請注意,根據此錯誤 ,如果每個進程資源限制停止JVM分配堆區域,您將收到錯誤消息。)

  • 這也可能是“過度提交”問題; 例如,如果您的應用程序在虛擬環境中運行,並且整個系統無法滿足需求,因為來自其他虛擬機的競爭太多。


建議的其他一些想法(IMO)不太可能:

  • 切換JRE不太可能有任何區別。 我從未在特定的64位JVM中聽到或看到任意內存限制。

  • 它不太可能是由於沒有足夠的連續內存。 當然不需要連續的物理內存。 唯一的可能是交換設備上的連續空間,但我不記得這是典型Linux操作系統的問題。


任何人都可以建議解決方案/解決方法嗎?

  • 檢查ulimit

  • 編寫一個小型的C程序,嘗試對大量內存進行malloc ,並查看在失敗之前可以分配多少內存。

  • 向系統(或管理程序)管理員尋求幫助。

(已編輯,請參閱有關交換空間的添加部分)

SHMMAX和SHMALL

由於您使用的是CentOS,因此您可能遇到類似於SHMMAXSHMALL內核設置的問題,如此處所述,用於配置Oracle DB 在同一鏈接下是獲取和設置正確SHMALL設置的示例計算。

連續的記憶

某些用戶已經報告說沒有足夠的連續內存,其他用戶表示這是無關緊要的。

我不確定CentOS上的JVM是否需要連續的內存塊。 根據SAS的說法 ,碎片化內存可能會阻止您的JVM使用大型Xmx啟動或啟動Xms內存設置,但互聯網上的其他聲明稱無關緊要。 我嘗試在我的48GB Windows工作站上證明或取消該聲明,但設法以初始和最大設置40GB啟動JVM。 我很確定沒有這種大小的連續塊可用,但是不同操作系統上的JVM可能表現不同,因為每個操作系統的內存管理可能不同(即,Windows通常會隱藏單個進程的物理地址)。

尋找最大的連續內存塊

使用/proc/meminfo查找可用的最大連續內存塊,請參閱VmAllocChunk下的值。 是所有價值觀的指南和解釋 如果您看到的值小於300GB,請嘗試一個低於VmAllocChunk值的值。

但是,通常這個數字高於物理可用內存(因為它是可用的虛擬內存值),它可能會給你誤報。 這是您可以保留的值,但一旦開始使用它,可能需要交換。 因此,您還應檢查MemFreeInactive值。 相反,您還可以查看整個列表,看看哪些值不超過300GB。

您可以檢查64位JVM的其他調整選項

我不知道為什么你似乎遇到300GB的內存限制問題。 有那么一刻,我以為你可能會打到最多的頁面。 默認值為4kB,300GB提供78,643,200頁。 看起來不像一些眾所周知的神奇數字。 例如,如果2^24是最大值,那么16,777,216頁或64GB應該是理論上可分配的最大值。

但是,假設為了論證你需要更大的頁面(事實證明,對於大型內存Java應用程序的性能更好),你應該參考JBoss上的這個手冊頁 ,它解釋了如何使用-XX:+UseLargePages並設置kernel.shmmax (再次出現), vm.nr_hugepagesvm.huge_tlb_shm_group (不確定后者是否需要)。

強調你的系統

其他人已經提出過這個建議。 要找出問題在於JVM而不是操作系統,你應該對它進行壓力測試。 您可以使用的一個工具是Stresslinux 在本教程中 ,您將找到可以使用的一些選項。 您特別感興趣的是以下命令:

stress --vm 2 --vm-bytes 300G --timeout 30s --verbose

如果該命令失敗或鎖定了您的系統,您就會知道操作系統正在限制使用該內存量。 如果成功,我們應該嘗試調整JVM,以便它可以使用可用內存。

編輯Apr6:檢查交換空間

具有非常大的內部存儲器大小的系統,使用很少或沒有交換空間的情況並不少見。 對於許多應用程序,這可能不是問題,但JVM要求交換可用交換空間大於請求的內存大小。 根據這個錯誤報告 ,JVM將嘗試增加交換空間本身,但是,正如這個SO線程中的一些答案所暗示的那樣 ,JVM可能並不總是能夠這樣做。

因此:使用cat /proc/swaps # free檢查當前可用的交換空間,如果小於300GB,請按照此CentOS聯機幫助頁上的說明增加系統的交換空間。

注1:我們可以從bugreport#4719001中扣除一個連續的可用交換空間塊不是必需的。 但是如果您不確定,請刪除所有交換空間並重新創建它 ,這應該刪除任何碎片。

注2:我見過幾個職位像這樣一個報告0MB交換空間, 能夠運行JVM。 這可能是由於JVM增加了交換空間本身。 嘗試手動增加交換空間以確定它是否能解決您的問題仍然沒有壞處。

結論不成熟

我意識到上述情況不是你問題的開箱即用的答案。 我希望它能為您提供一些指導,但您可以嘗試使JVM正常工作。 您可能還嘗試其他JVM,如果問題證明是您當前使用的JVM的限制,但從我到目前為止所讀到的,對64位JVM不應施加限制。

你在初始化JVM時得到的錯誤讓我相信問題不在於JVM,而在於操作系統無法滿足300GB內存的預留。

我自己的測試表明,JVM可以訪問所有虛擬內存,而不關心可用的物理內存量。 如果虛擬內存低於物理內存,那將是奇怪的,但VmAllocChunk設置應該給你一個方向提示(它通常要大得多)。

如果您查看Java HotSpot VM的FAQ部分 ,它提到在64位VM上,只有64個地址位可供使用,因此最大Java堆大小取決於物理內存和交換空間的大小出現在系統上。

如果你在理論上計算然后你可以有18446744073709551616 MB的內存,但它有上述限制。

您必須使用-Xmx命令為JVM定義最大堆大小。 默認情況下 ,Java在64位JVM上使用64 + 30%= 83.2MB。

我在我的機器上嘗試了以下命令,它看起來工作正常。

java -Xmx500g com.test.TestClass

我也嘗試用TB來定義最大堆,但它不起作用。

運行ulimit -a作為JVM Process的用戶,並驗證您的內核不限制您的最大內存大小。 您可能需要編輯/etc/security/limit.conf

根據此討論 ,LSF不會將節點內存池化為單個共享空間。 你正在使用別的東西。 閱讀那些東西的文檔,因為它可能無法完成你要求它做的事情。 特別是,它可能無法分配跨越所有節點的單個連續內存區域。 通常這不是必需的,因為應用程序會對malloc進行多次調用。 但是JVM為自己簡化了事情,希望通過有效地調用malloc一次為整個堆分配(或保留)一個連續的區域。 或者它可能與您用來模擬巨型共享內存機器的其他內容相關。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM