JVM內存最大能調多大分析-轉帖

JVM內存最大能調多大分析【經典】

上次用weblogic 把 -XmxXXXX 設成2G,就啓動不起來,設小點就起來了,當時很氣,怎麼2G都起不了,今天在看到了一篇解釋,轉過來了
這 次一位老友提出了這個問題,記得當年一個java高手在blogjava提出後,被罵得半死。大家使用java -XmxXXXX -version版本得出了不同的結論。後來老友說大概是1800M左右,我當時反駁,“我設置過服務器8G內存,我使用兩個tomcat,每個2G”。 爲此,我翻開所有的JVM的內存管理的c代碼,沒有任何結論。我不是linux內核程序員,但是我看過linux的源碼,知道32位體系結構的計算機尋址 空間是2^32=4G,intel Pentium Pro處理器尋址空間是36位,CPU內部增加了PAE寄存器。用於處理多出來的4根地址
線 的使用,所以PAE的技術實現最大2^36=64G尋址。通過linux的內核源碼,標準Linux內核對於物理內存的管理採用1:3的分配比例,即物理 內存的1/4爲內核空間(kernel space),剩下的3/4爲用戶進程空間(user space),因此,在一臺4G內存的服務器上,用戶進程可使用的內存最大也就是3G。當進程被內核調入CPU運行時,不同的地址空間數據會被調入4G以 內的用戶進程空間,其實就能用3G。 IA32架構上,單一進程是不能使用超過4G的內存空間的。但是我記得我給mysql server分配內存大約是1.7G左右,不是2的32次方-1,我分配java 2G內存的計算機是IBM的RS6000.
經過不同平臺的測 試,我得出了大概的數值,win2k下1.6G左右,nt下1.2G,原因是這樣的,Classic VM and HotSpot VM 存放用戶區的連續地址中,NT把 kernel DLLs 放在 0x7c 開頭的地址空間,所以nt下只有<2G的空間,所以JVM heap 使用極限是2G.用戶的dll開始於0x77000000,用戶的應用程序開始於0x00400000.我現在唯一確定的是sun可能爲了防止和某些 JVM插件的衝突,把dll的地址給rebase一下,這樣使用的空間就很少了一部分.爲什末rebase,原因是這樣的,因爲在windows下編譯 dll 的默認地址都是10000000, 一般在release之前的時候要rebase一下,rebase 的 -b 這個參數是指定一個起始地址,MSDN建議地址是0x60000000,這個工具隨visual studio和platform SDK發放。
例 如
rebase.exe -b 0x6D000000 \jdk\jre\bin\*.dll \jdk\jre\bin\hotspot\jvm.dll這樣你的JVM用的內存多一些,目前關於這個我只能得到BEA的 JRockit最大也只能使用1.8G內存,看來各家編譯JDK時都作了些手腳.
目前只能得到bea的的-Xmx最小值是16 MB,sun的資料很不全,還好java開源了,可以不依靠sun了.

sun提供的資料
Maximum Address Space Per Process  

Operating System                   Maximum Address Space Per Process

Redhat Linux 32 bit                                      2 GB

Redhat Linux  64 bit                                     3 GB

Windows 98/2000/NT/Me/XP                                  2 GB

Solaris x86 (32 bit)                                      4 GB

Solaris 32 bit                                            4 GB

Solaris 64 bit                                            Terabytes
以 上文檔有誤,32位的redhat Server利用 Highmem技術可以使用3G內存.
solaris不愧是java的誕生平臺。

問了一下bea的工程師,得出大致的結論,
Windows 2003/XP using the /3GB switch (32-bit OS)
1.85 GB - JRockit 5.0 R25.2 (SP2)
2.85 GB - JRockit 5.0 R26 (SP3)

Windows 2003/XP x64 Edition with a 32-bit JVM (64-bit OS)
2.05 GB - JRockit 5.0 R25.2 (SP2)
3.85 GB - JRockit 5.0 R26 (SP3)

對於windows 2000打開3G模式,windows核心編程說得很清楚,boot.ini加入/3G參數。

[boot loader]
timeout=30
default=multi(0)disk(0)rdisk(0)partition(2)\WINNT
[operating systems]
multi(0)disk(0)rdisk(0)partition(2)\WINNT="????" /3GB

Note: "????" in the previous example can be the programmatic name of any of the following operating system versions:

Windows XP Professional
Windows Server 2003
Windows Server 2003, Enterprise Edition
Windows Server 2003, Datacenter Edition
Windows 2000 Advanced Server
Windows 2000 Datacenter Server
Windows NT Server 4.0, Enterprise Edition

在我的機子測試一把,我的自己配置,1G內存,winXP

沒有打開3G模式,sun的jdk 1.6 java -Xmx1447M -version,揪出錯了,jrockit-R27.1.0-jdk1.5.0_08爲1911M,3G模式 sun的jdk沒有變化,IBM J9 VM (build 2.3, J2RE 1.5.0 IBM J9 2.3 Windows XP x86-32 j9vmwi3223-2006050
4 (JIT enabled) 3G和2G相同,java -Xmx1787M -version 就出問題,jrockit-R27.1.0-jdk1.5.0_08爲2899M,注意Xmx的內存不是物 理內存,我的機子物理內存只有1G
jrockit不愧爲java第一虛擬機,只可惜不開源。




今天分析了當前比較流行的幾個不同公司不同版本JVM的最大內存,得出來的結果如下:

公司 JVM版本 最大內存(兆)client 最大內存(兆)server
SUN 1.5.x 1492 1520
SUN 1.5.5(Linux) 2634 2660
SUN 1.4.2 1564 1564
SUN 1.4.2(Linux) 1900 1260
IBM 1.4.2(Linux) 2047 N/A
BEA JRockit 1.5 (U3) 1909 1902



除非特別說明,否則JVM版本都運行在Windows操作系統下

附:如何獲得JVM的最大可用內存

在命令行下用 java -Xmx1200m -XX:Max Perm Size=60m -version 命令來進行測試,然後逐漸的增大XXXX的值,如果執行正常就表示指定的內存大小可用,否則會打印錯誤信息。
最後得到的虛擬機實際分配到的
總內存大小= 堆內存+ 非堆內存
1200m:爲堆內存大小,如果不指定後者參數則有最大數限制,網上很多文章認爲這就是JVM內存, -Xmx 爲設置最大堆內存
60m:
爲非堆內存大小, -XX: Max PermSize 實爲 永久域內存,在堆內存之外,屬於非堆內存部分,jdk1.5我測了好像默認爲62m,即得到非堆部分默認內存)

Sun HotSpot 1.4.1使用分代收集器,它把堆分爲三個主要的域:新域、舊域以及永久域。Sun JVM生成的所有新對象放在新域中。一旦對象經歷了一定數量的垃圾收集循環後,便獲得使用期並進入舊域。在永久域中Sun JVM則存儲class和method對象。就配置而言,永久域是一個獨立域並且不認爲是堆的一部分。

實際發現版本上有細微差別的JDK最大容許內存值都不盡相同,因此在實際的應用中還是要自己試驗一下看到底內存能達到什麼樣的值。

通過這個表想說明的是,如果你的機器的內存太多的話,只能通過多運行幾個實例來提供機器的利用率了,例如跑Tomcat ,你可以多裝幾 個Tomcat 並 做集羣,依此類推。

≡≡≡ 網友評論 ≡≡≡
東子 網友說:
Windows 下的最大內存應該跟NT內核對地址空間的保留也有關係, 好像默認情況下NT內核要佔用高2G的地址空間, 所以應用程序撐死能獲得的內存不會超過2G; 記得有一個參數可以讓NT只佔1G內存, 這樣應用程序就有3G地址空間可用, 相應環境下JVM能允許的最大內存可能也會升高.

at 05-10-06 00:04
purpureleaf 網友說:
windows的每個應用(不是尋址)的尋址空間一般是2g或者3g,取決於一個參數。但是隻要使用一組特定的函數分配內存,每個應用的尋址空間可以遠遠 超過4g

jdk可能是設置不了那個大的內存,但那不是windows造成的,是jdk造成的,在linux上一樣設置不了。看來做java的朋友對windows 還是不熟
發佈了70 篇原創文章 · 獲贊 0 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章