现在的位置: 首页 > 综合 > 正文

JVM内存分配

2013年08月27日 ⁄ 综合 ⁄ 共 1678字 ⁄ 字号 评论关闭

如果对JVM的内存分配不合理,应用程序运行中常常用抛出java.lang.OutOfMemory和java.lang.OutOfMemoryError: PermGen space异常。

所以我们要对JVM调优以避免出现此类问题。

JVM的内存分配主要通过这几个参数设定:-Xms -Xmx -XX:PermSize -XX:MaxPermSize

我们先对几个概念进行解释:

 

      ◆堆(Heap)和非堆(Non-heap)内存

  按照官方的说法:“Java 虚拟机具有一个堆,堆是运行时数据区域,
所有类实例和数组的内存均从此处分配。堆是在 Java 虚拟机启动时创建的。”在JVM中堆之外的内存称为非堆内存(Non-heap
memory)”。可以看出JVM主要管理两种类型的内存:堆和非堆。简单来说堆就是Java代码可及的内存,是留给开发人员使用的;非堆就是JVM留给自己用的,所以方法区、JVM内部处理或优化所需的内存(如JIT编译后的代码缓存)、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法
的代码都在非堆内存中。

    堆内存主要存放类实例(Instance)等,而非堆区为java永久生成对象(Permanate generation)如,class对象、方法对象这些可反射(reflective)对象分配内存,Class被loader的时候就会被放到非堆区。

  ◆堆内存分配

  JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4。默认空余堆内
存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。因此服务器一般设置
-Xms、-Xmx相等以避免在每次GC 后调整堆的大小。

      说明:如果-Xmx不指定或者指定偏小,应用可能会导致java.lang.OutOfMemory错误,此错误来自JVM不是Throwable的,无法用try...catch捕捉。

  ◆非堆内存分配

  JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。

     如果应用程序使用了大量第三方的jar包,非堆内存分配过小就会导致:java.lang.OutOfMemoryError: PermGen space。GC(Garbage Collection)不会在主程序运行期对PermGen
space进行清理,所以如果你的APP会LOAD很多CLASS的话,就很可能出现PermGen
space错误。这种错误常见在web服务器对JSP进行pre compile的时候。

  ◆JVM内存限制(最大值)

  首先JVM内存限制于实际的最大物理内存(废话!呵呵),假设物理内存无限大的话,JVM内存的最大值跟操作系统有很大的关系。简单的说就32位处理器虽然可控内存空间有4GB,但是具体的操作系统会给一个限制,这个限制一般是2GB-3GB(一般来说Windows系统下为1.5G-2G,Linux系统下为2G-3G),而64bit以上的处理器就不会有限制了。

      通过上面对JVM内存管理的介绍我们已经了解到JVM内存包含两种:堆内存和非堆内存,另外JVM最大内存首先取决于实际的物理内存和操作系统。

      我们在实际配置中还要注意以下几点:

 

      1) 参数中-Xms的值大于-Xmx,或者-XX:PermSize的值大于-XX:MaxPermSize;

  2)
-Xmx的值和-XX:MaxPermSize的总和超过了JVM内存的最大限制,比如当前操作系统最大内存限制,或者实际的物理内存等等。说到实际物理
内存这里需要说明一点的是,如果你的内存是1024MB,但实际系统中用到的并不可能是1024MB,因为有一部分被硬件占用了。

 

 

示例:-Xmx1024m -Xms1024m -XX:PermSize:256m -XX:MaxPermSize:512m

 

 

抱歉!评论已关闭.