jvm中堆空间划分

在jvm中堆空间划分为三个代:年轻代(Young Generation)、年老代(Old Generation)和永久代(Permanent Generation)。年轻代和年老代是存储动态产生的对象。永久带主要是存储的是java的类信息,包括解析得到的方法、属性、字段等等。永久带基本 不参与垃圾回收。我们这里讨论的垃圾回收主要是针对年轻代和年老代。具体如下图。

jvm-heap

年轻代又分成3个部分,一个eden区和两个相同的survior区。刚开始创建的对象都是放置在eden区的。分成这样3个部分,主要是为了生命 周期短的对象尽量留在年轻带。当eden区申请不到空间的时候,进行minorGC,把存活的对象拷贝到survior。年老代主要存放生命周期比较长的 对象,比如缓存对象。具体jvm内存回收过程描述如下(可以结合上图):

1、对象在Eden区完成内存分配
2、当Eden区满了,再创建对象,会因为申请不到空间,触发minorGC,进行young(eden+1survivor)区的垃圾回收
3、minorGC时,Eden不能被回收的对象被放入到空的survivor(Eden肯定会被清空),另一个survivor里不能被GC回收的对象也会被放入这个survivor,始终保证一个survivor是空的
4、当做第3步的时候,如果发现survivor满了,则这些对象被copy到old区,或者survivor并没有满,但是有些对象已经足够Old,也被放入Old区 XX:MaxTenuringThreshold
5、当Old区被放满的之后,进行fullGC

在知道垃圾回收机制以后,大家可以在对jvm中堆的各个参数进行优化设置,来提高性能。

=============

当一个URL被访问时,内存申请过程如下:

A.JVM会试图为相关Java对象在Eden中初始化一块内存区域

B.当Eden空间足够时,内存申请结束。否则到下一步

C.JVM试图释放在Eden中所有不活跃的对象(这属于1或更高级的JVM垃圾回收);释放后若Eden空间仍然不足以放入新对象,则试图将部分

Eden中活跃对象放入Survivor区/OLD区

D.Survivor区被用来作为Eden及OLD的中间交换区域,当OLD区空间足够时,Survivor区的对象会被移到Old区,否则会被保留在Survivor区

E.当OLD区空间不够时,JVM会在OLD区进行完全的垃圾收集(0级)

F.完全垃圾收集后,若Survivor及OLD区仍然无法存放从Eden复制过来的部分对象,导致JVM无法在Eden区为新对象创建内存区域,则出现”outofmemory错误”。下面看一下JVM垃圾回收机制的Java堆的相关参数。

Java堆相关参数:

ms/mx:定义YOUNG+OLD段的总尺寸,ms为JVM启动时YOUNG+OLD的内存大小;mx为最大可占用的YOUNG+OLD内存大小。在用户生产环境上一般将这两个值设为相同,以减少运行期间系统在内存申请上所花的开销。

NewSize/MaxNewSize:定义YOUNG段的尺寸,NewSize为JVM启动时YOUNG的内存大小;MaxNewSize为最大可占用的YOUNG内存大小。在用户生产环境上一般将这两个值设为相同,以减少运行期间系统在内存申请上所花的开销。

PermSize/MaxPermSize:定义Perm段的尺寸,PermSize为JVM启动时Perm的内存大小;MaxPermSize为最大可占用的Perm内存大小。在用户生产环境上一般将这两个值设为相同,以减少运行期间系统在内存申请上所花的开销。

SurvivorRatio:设置Survivor空间和Eden空间的比例

例:

[java]

MEM_ARGS=”-Xms512m-Xmx512m
-XX:NewSize=256m-XX:MaxNewSize=256m
-XX:PermSize=128m-XX:MaxPermSize=128m
-XX:SurvivorRatio=6”

[/java]

在上面的例子中:

[java]

YOUNG+OLD:512M
YOUNG:256M
Perm:128M
Eden:YOUNG*6/(6+1+1)=192M
Survivor:YOUNG/(6+1+1)=32M

[/java]

Java堆的总尺寸=YOUNG+OLD+Perm=640M