您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 项目/工程管理 > JVM内存最大能调多大分析
JVM内存最大能调多大分析【经典】2010-11-1013:21转载自suofang最终编辑suofang上次用weblogic把-XmxXXXX设成2G,就启动不起来,设小点就起来了,当时很气,怎么2G都起不了,今天在看到了一篇解释,转过来了这次一位老友提出了这个问题,记得当年一个java高手在blogjava提出后,被骂得半死。大家使用java-XmxXXXX-version版本得出了不同的结论。后来老友说大概是1800M左右,我当时反驳,“我设置过服务器8G内存,我使用两个tomcat,每个2G”。为此,我翻开所有的JVM的内存管理的c代码,没有任何结论。我不是linux内核程序员,但是我看过linux的源码,知道32位体系结构的计算机寻址空间是2^32=4G,intelPentiumPro处理器寻址空间是36位,CPU内部增加了PAE寄存器。用于处理多出来的4根地址线的使用,所以PAE的技术实现最大2^36=64G寻址。通过linux的内核源码,标准Linux内核对于物理内存的管理采用1:3的分配比例,即物理内存的1/4为内核空间(kernelspace),剩下的3/4为用户进程空间(userspace),因此,在一台4G内存的服务器上,用户进程可使用的内存最大也就是3G。当进程被内核调入CPU运行时,不同的地址空间数据会被调入4G以内的用户进程空间,其实就能用3G。IA32架构上,单一进程是不能使用超过4G的内存空间的。但是我记得我给mysqlserver分配内存大约是1.7G左右,不是2的32次方-1,我分配java2G内存的计算机是IBM的RS6000.经过不同平台的测试,我得出了大概的数值,win2k下1.6G左右,nt下1.2G,原因是这样的,ClassicVMandHotSpotVM存放用户区的连续地址中,NT把kernelDLLs放在0x7c开头的地址空间,所以nt下只有2G的空间,所以JVMheap使用极限是2G.用户的dll开始于0x77000000,用户的应用程序开始于0x00400000.我现在唯一确定的是sun可能为了防止和某些JVM插件的冲突,把dll的地址给rebase一下,这样使用的空间就很少了一部分.为什末rebase,原因是这样的,因为在windows下编译dll的默认地址都是10000000,一般在release之前的时候要rebase一下,rebase的-b这个参数是指定一个起始地址,MSDN建议地址是0x60000000,这个工具随visualstudio和platformSDK发放。例如rebase.exe-b0x6D000000\jdk\jre\bin\*.dll\jdk\jre\bin\hotspot\jvm.dll这样你的JVM用的内存多一些,目前关于这个我只能得到BEA的JRockit最大也只能使用1.8G内存,看来各家编译JDK时都作了些手脚.目前只能得到bea的的-Xmx最小值是16MB,sun的资料很不全,还好java开源了,可以不依靠sun了.sun提供的资料MaximumAddressSpacePerProcessOperatingSystemMaximumAddressSpacePerProcessRedhatLinux32bit2GBRedhatLinux64bit3GBWindows98/2000/NT/Me/XP2GBSolarisx86(32bit)4GBSolaris32bit4GBSolaris64bitTerabytes以上文档有误,32位的redhatServer利用Highmem技术可以使用3G内存.solaris不愧是java的诞生平台。问了一下bea的工程师,得出大致的结论,Windows2003/XPusingthe/3GBswitch(32-bitOS)1.85GB-JRockit5.0R25.2(SP2)2.85GB-JRockit5.0R26(SP3)Windows2003/XPx64Editionwitha32-bitJVM(64-bitOS)2.05GB-JRockit5.0R25.2(SP2)3.85GB-JRockit5.0R26(SP3)对于windows2000打开3G模式,windows核心编程说得很清楚,boot.ini加入/3G参数。[bootloader]timeout=30default=multi(0)disk(0)rdisk(0)partition(2)\WINNT[operatingsystems]multi(0)disk(0)rdisk(0)partition(2)\WINNT=????/3GBNote:????inthepreviousexamplecanbetheprogrammaticnameofanyofthefollowingoperatingsystemversions:WindowsXPProfessionalWindowsServer2003WindowsServer2003,EnterpriseEditionWindowsServer2003,DatacenterEditionWindows2000AdvancedServerWindows2000DatacenterServerWindowsNTServer4.0,EnterpriseEdition在我的机子测试一把,我的自己配置,1G内存,winXP没有打开3G模式,sun的jdk1.6java-Xmx1447M-version,揪出错了,jrockit-R27.1.0-jdk1.5.0_08为1911M,3G模式sun的jdk没有变化,IBMJ9VM(build2.3,J2RE1.5.0IBMJ92.3WindowsXPx86-32j9vmwi3223-20060504(JITenabled)3G和2G相同,java-Xmx1787M-version就出问题,jrockit-R27.1.0-jdk1.5.0_08为2899M,注意Xmx的内存不是物理内存,我的机子物理内存只有1G。jrockit不愧为java第一虚拟机,只可惜不开源。今天分析了当前比较流行的几个不同公司不同版本JVM的最大内存,得出来的结果如下:公司JVM版本最大内存(兆)client最大内存(兆)serverSUN1.5.x14921520SUN1.5.5(Linux)26342660SUN1.4.215641564SUN1.4.2(Linux)19001260IBM1.4.2(Linux)2047N/ABEAJRockit1.5(U3)19091902除非特别说明,否则JVM版本都运行在Windows操作系统下附:如何获得JVM的最大可用内存在命令行下用java-Xmx1200m-XX:MaxPermSize=60m-version命令来进行测试,然后逐渐的增大XXXX的值,如果执行正常就表示指定的内存大小可用,否则会打印错误信息。最后得到的虚拟机实际分配到的总内存大小=堆内存+非堆内存1200m:为堆内存大小,如果不指定后者参数则有最大数限制,网上很多文章认为这就是JVM内存,-Xmx为设置最大堆内存60m:为非堆内存大小,-XX:MaxPermSize实为永久域内存,在堆内存之外,属于非堆内存部分,jdk1.5我测了好像默认为62m,即得到非堆部分默认内存)SunHotSpot1.4.1使用分代收集器,它把堆分为三个主要的域:新域、旧域以及永久域。SunJVM生成的所有新对象放在新域中。一旦对象经历了一定数量的垃圾收集循环后,便获得使用期并进入旧域。在永久域中SunJVM则存储class和method对象。就配置而言,永久域是一个独立域并且不认为是堆的一部分。实际发现版本上有细微差别的JDK最大容许内存值都不尽相同,因此在实际的应用中还是要自己试验一下看到底内存能达到什么样的值。通过这个表想说明的是,如果你的机器的内存太多的话,只能通过多运行几个实例来提供机器的利用率了,例如跑Tomcat,你可以多装几个Tomcat并做集群,依此类推。≡≡≡网友评论≡≡≡东子网友说:Windows下的最大内存应该跟NT内核对地址空间的保留也有关系,好像默认情况下NT内核要占用高2G的地址空间,所以应用程序撑死能获得的内存不会超过2G;记得有一个参数可以让NT只占1G内存,这样应用程序就有3G地址空间可用,相应环境下JVM能允许的最大内存可能也会升高.at05-10-0600:04purpureleaf网友说:windows的每个应用(不是寻址)的寻址空间一般是2g或者3g,取决于一个参数。但是只要使用一组特定的函数分配内存,每个应用的寻址空间可以远远超过4gjdk可能是设置不了那个大的内存,但那不是windows造成的,是jdk造成的,在linux上一样设置不了。看来做java的朋友对windows还是不熟
本文标题:JVM内存最大能调多大分析
链接地址:https://www.777doc.com/doc-2882366 .html