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了.java

sun提供的資料
Maximum Address Space Per Process  
mysql

Operating System                   Maximum Address Space Per Processlinux

Redhat Linux 32 bit                                      2 GB程序員

Redhat Linux  64 bit                                     3 GBweb

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

Solaris x86 (32 bit)                                      4 GB編程

Solaris 32 bit                                            4 GBwindows

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

問了一下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:MaxPermSize=60m -version 命令來進行測試,而後逐漸的增大XXXX的值,若是執行正常就表示指定的內存大小可用,不然會打印錯誤信息。
最後獲得的虛擬機實際分配到的 
總內存大小=堆內存+非堆內存
1200m:爲堆內存大小,若是不指定後者參數則有最大數限制,網上不少文章認爲這就是JVM內存,-Xmx爲設置最大堆內存
60m:
爲非堆內存大小,-XX:MaxPermSize實爲永久域內存,在堆內存以外,屬於非堆內存部分,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 仍是不熟

相關文章
相關標籤/搜索