天天看点

Java虚拟机支持的最大内存限制

最近在开发的程序。本来我是一直很喜欢的内存管理的,不需要担心分配内存,只管分配,垃圾收集器自己会给你回收内存的。现在开发的程序数据量很大,为了速度快,我准备把所有的信息加载进内存,这样可以保证快速响应。我还在反复算内存,想想自己的数据量,现在刚开始的时候应该够了(我的机器是4g内存,虽然就认3.5g,但是比起我现在的数据量应该没问题)。

  没想到第一个实验的程序,跑了几个小时,就遇到了out of memory exception了。看看自己的虚拟机设置,我设置的是-xms512m

-xmx1024m。想都没想,直接改成-xms512m -xmx2048m,结果直接就could not reserve enough space for

object heap。程序都起不来了。这才发现原来最大内存还有限制。上网搜了一下,发现很多讨论这个问题的文章。最终在bea的dev2dev论坛发现了最有用的

一篇

  这里的版主yulimin 做了,得出结论:

  公司

jvm版本                 

最大内存(兆)client    最大内存(兆)server

  sun

1.5.x                         

1492                           

1520

1.5.5(linux)            

2634                           

2660

1.4.2                         

1564                           

1564

1.4.2(linux)            

1900                           

1260

  ibm

2047                            

n/a

  bea jrockit 1.5 (u3)     

1909                            

1902

  我现在用的是jdk1.6. 0_05,了一下。在client状态下最大是,我的jdk不认-server参数,测试不了server状态。估计差不多。

1.6.0                         

1442                          

  看样子用java想用大内存也是不可能的了。而且一般的说法是内存太大了,垃圾收集的时间就会长。这也可以理解,一般是内存不够用了才收集的,扫描2g内存比1g当然要慢多了,而且内存对象多了,估计关系是指数上升的。

  下面附上yulimin的测试方法和测试记录。

  测试方法:在命令行下用 java -xmxxxxxm -version

命令来进行测试,然后逐渐的增大xxxx的值,如果执行正常就表示指定的内存大小可用,否则会打印错误信息。

堆(heap)和非堆(non-heap)内存

按照官方的说法:“java

虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配。堆是在 java

虚拟机启动时创建的。”“在jvm中堆之外的内存称为非堆内存(non-heap

memory)”。可以看出jvm主要管理两种类型的内存:堆和非堆。简单来说堆就是java代码可及的内存,是留给开发人员使用的;非堆就是jvm留给

自己用的,所以方法区、jvm内部处理或优化所需的内存(如jit编译后的代码缓存)、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法

的代码都在非堆内存中。

堆内存分配

jvm初始分配的内存由-xms指定,默认是物理内存的1/64;jvm最大分配的内存由

-xmx指定,默认是物理内存的1/4。默认空余堆内存小于40%时,jvm就会增大堆直到-xmx的最大限制;空余堆内存大于70%时,jvm会减少堆

直到-xms的最小限制。因此服务器一般设置-xms、-xmx相等以避免在每次gc 后调整堆的大小。

非堆内存分配

jvm使用-xx:permsize设置非堆内存初始值,默认是物理内存的1/64;由xx:maxpermsize设置最大非堆内存的大小,默认是物理内存的1/4。

jvm内存限制(最大值)

首先jvm内存限制于实际的最大物理内存(废话!呵呵),假设物理内存无限

大的话,jvm内存的最大值跟操作系统有很大的关系。简单的说就32位处理器虽然可控内存空间有4gb,但是具体的操作系统会给一个限制,这个限制一般是

2gb-3gb(一般来说windows系统下为1.5g-2g,linux系统下为2g-3g),而64bit以上的处理器就不会有限制了。

所以说设置vm参数导致程序无法启动主要有以下几种原因:

1) 参数中-xms的值大于-xmx,或者-xx:permsize的值大于-xx:maxpermsize; 2) -xmx的值和-xx:maxpermsize的总和超过了jvm内存的最大限制,比如当前操作系统最大内存限制,或者实际的物理内存等等。说到实际物理 内存这里需要说明一点的是,如果你的内存是1024mb,但实际系统中用到的并不可能是1024mb,因为有一部分被硬件占用了。
Java虚拟机支持的最大内存限制