上次用weblogic 把 -XmxXXXX 設(shè)成2G,就啟動不起來,設(shè)小點就起來了,當(dāng)時很氣,怎么2G都起不了,今天在看到了一篇解釋,轉(zhuǎn)過來了
這 次一位老友提出了這個問題,記得當(dāng)年一個java高手在blogjava提出后,被罵得半死。大家使用java -XmxXXXX -version版本得出了不同的結(jié)論。后來老友說大概是1800M左右,我當(dāng)時反駁,“我設(shè)置過服務(wù)器8G內(nèi)存,我使用兩個tomcat,每個2G”。 為此,我翻開所有的JVM的內(nèi)存管理的c代碼,沒有任何結(jié)論。我不是linux內(nèi)核程序員,但是我看過linux的源碼,知道32位體系結(jié)構(gòu)的計算機尋址 空間是2^32=4G,intel Pentium Pro處理器尋址空間是36位,CPU內(nèi)部增加了PAE寄存器。用于處理多出來的4根地址
線 的使用,所以PAE的技術(shù)實現(xiàn)最大2^36=64G尋址。通過linux的內(nèi)核源碼,標(biāo)準Linux內(nèi)核對于物理內(nèi)存的管理采用1:3的分配比例,即物理 內(nèi)存的1/4為內(nèi)核空間(kernel space),剩下的3/4為用戶進程空間(user space),因此,在一臺4G內(nèi)存的服務(wù)器上,用戶進程可使用的內(nèi)存最大也就是3G。當(dāng)進程被內(nèi)核調(diào)入CPU運行時,不同的地址空間數(shù)據(jù)會被調(diào)入4G以 內(nèi)的用戶進程空間,其實就能用3G。 IA32架構(gòu)上,單一進程是不能使用超過4G的內(nèi)存空間的。但是我記得我給mysql server分配內(nèi)存大約是1.7G左右,不是2的32次方-1,我分配java 2G內(nèi)存的計算機是IBM的RS6000.
經(jīng)過不同平臺的測 試,我得出了大概的數(shù)值,win2k下1.6G左右,nt下1.2G,原因是這樣的,Classic VM and HotSpot VM 存放用戶區(qū)的連續(xù)地址中,NT把 kernel DLLs 放在 0x7c 開頭的地址空間,所以nt下只有<2G的空間,所以JVM heap 使用極限是2G.用戶的dll開始于0x77000000,用戶的應(yīng)用程序開始于0x00400000.我現(xiàn)在唯一確定的是sun可能為了防止和某些 JVM插件的沖突,把dll的地址給rebase一下,這樣使用的空間就很少了一部分.為什末rebase,原因是這樣的,因為在windows下編譯 dll 的默認地址都是10000000, 一般在release之前的時候要rebase一下,rebase 的 -b 這個參數(shù)是指定一個起始地址,MSDN建議地址是0x60000000,這個工具隨visual studio和platform SDK發(fā)放。
例 如
rebase.exe -b 0x6D000000 \jdk\jre\bin\*.dll \jdk\jre\bin\hotspot\jvm.dll這樣你的JVM用的內(nèi)存多一些,目前關(guān)于這個我只能得到BEA的 JRockit最大也只能使用1.8G內(nèi)存,看來各家編譯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技術(shù)可以使用3G內(nèi)存.
solaris不愧是java的誕生平臺。
問了一下bea的工程師,得出大致的結(jié)論,
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參數(shù)。
[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內(nèi)存,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的內(nèi)存不是物 理內(nèi)存,我的機子物理內(nèi)存只有1G。
jrockit不愧為java第一虛擬機,只可惜不開源。
今天分析了當(dāng)前比較流行的幾個不同公司不同版本JVM的最大內(nèi)存,得出來的結(jié)果如下:
公司 JVM版本 最大內(nèi)存(兆)client 最大內(nèi)存(兆)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操作系統(tǒng)下
附:
如何獲得JVM的最大可用內(nèi)存 在命令行下用 java -Xmx1200m -XX:MaxPermSize=60m -version 命令來進行測試,然后逐漸的增大XXXX的值,如果執(zhí)行正常就表示指定的內(nèi)存大小可用,否則會打印錯誤信息。
最后得到的虛擬機實際分配到的
總內(nèi)存大小=堆內(nèi)存+非堆內(nèi)存1200m:為堆內(nèi)存大小,如果不指定后者參數(shù)則有最大數(shù)限制,網(wǎng)上很多文章認為這就是JVM內(nèi)存,-Xmx為設(shè)置最大堆內(nèi)存
60m:為非堆內(nèi)存大小,-XX:MaxPermSize實為永久域內(nèi)存,在堆內(nèi)存之外,屬于非堆內(nèi)存部分,jdk1.5我測了好像默認為62m,即得到非堆部分默認內(nèi)存)Sun HotSpot 1.4.1使用分代收集器,它把堆分為三個主要的域:新域、舊域以及永久域。Sun JVM生成的所有新對象放在新域中。一旦對象經(jīng)歷了一定數(shù)量的垃圾收集循環(huán)后,便獲得使用期并進入舊域。在永久域中Sun JVM則存儲class和method對象。就配置而言,永久域是一個獨立域并且不認為是堆的一部分。實際發(fā)現(xiàn)版本上有細微差別的JDK最大容許內(nèi)存值都不盡相同,因此在實際的應(yīng)用中還是要自己試驗一下看到底內(nèi)存能達到什么樣的值。
通過這個表想說明的是,如果你的機器的內(nèi)存太多的話,只能通過多運行幾個實例來提供機器的利用率了,例如跑
Tomcat,你可以多裝幾 個
Tomcat并 做集群,依此類推。
≡≡≡ 網(wǎng)友評論 ≡≡≡
東子 網(wǎng)友說:
Windows下的最大內(nèi)存應(yīng)該跟NT內(nèi)核對地址空間的保留也有關(guān)系, 好像默認情況下NT內(nèi)核要占用高2G的地址空間, 所以應(yīng)用程序撐死能獲得的內(nèi)存不會超過2G; 記得有一個參數(shù)可以讓NT只占1G內(nèi)存, 這樣應(yīng)用程序就有3G地址空間可用, 相應(yīng)環(huán)境下JVM能允許的最大內(nèi)存可能也會升高.
at 05-10-06 00:04
purpureleaf 網(wǎng)友說:
windows的每個應(yīng)用(不是尋址)的尋址空間一般是2g或者3g,取決于一個參數(shù)。但是只要使用一組特定的函數(shù)分配內(nèi)存,每個應(yīng)用的尋址空間可以遠遠 超過4g
jdk可能是設(shè)置不了那個大的內(nèi)存,但那不是windows造成的,是jdk造成的,在linux上一樣設(shè)置不了。看來做java的朋友對windows 還是不熟