Java Heap
作用:主要用于存放对象实例和数组。
分区:Young Generation(Eden + From Survivor + To Survivor)+ Old Generation
目的:这样分区能更好的管理内存对象,包括内存的分配和回收。
- Young Generation
主要用于存放新生的对象。 - Old Generation
主要存放声明周期较长的内存对象。
堆大小 = Young + Old
默认情况下,Young :Old = 1 : 2 。
默认情况下,Young 的分区比例为,Eden : From : To = 8 : 1 : 1 。
JVM每次都会使用Eden和其中一个Survivor区域,所以,每次都只会用新生代90%的空间。
GC(Garbage Collection)
堆内存也是GC的主要区域,GC主要分为Minor GC、Full GC(或Major GC)。
Minor GC
Minor GC主要发生在Young Generation,采用复制算法。
当一个对象在Eden(+Survivor,假设是From)出生后,经过一次Minor GC后,若还存活着并且能被另一个Survivor(假设是To)所容纳,则用复制算法,将其复制到To Survivor区域,并且清理之前的Eden和From Survivor区域,将其年龄设置为1;之后每经过一次Minor GC,则将该对象年龄加1,直至达到某个值后,这些对象变为Old Generation。Full GC
Full GC主要发生在Old Generation,采用“标记-清除”和“标记-整理”算法。
对于一些较大的对象 ( 即需要分配一块较大的连续内存空间 ) 则是直接进入到老年代;
在Survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象,也可以直接进入老年代。
Full GC 发生的次数不会有 Minor GC 那么频繁,并且做一次 Full GC 要比进行一次 Minor GC 的时间更长。内存申请过程
1)JVM会试图为相关Java对象在Young的Eden区中初始化一块内存区域。当Eden区空间足够时,内存申请结束。2)若Eden内存不够,JVM试图释放在Eden区中所有不活跃的对象(Young GC)。释放后若Eden空间仍然不足以放入新对象,JVM则将部分Eden中活跃对象复制到Survivor区。
3)若Survivor空间不够,当Old空间足够时,Survivor区中存活了一定次数的对象会被移到Old。
4)当Old空间不够时,JVM会在Old进行完全的垃圾回收(Full GC)。
5)Full GC后,若Survivor及Old仍然无法存放从Eden区复制过来的对象,则会导致JVM无法在Eden区为新生成的对象申请内存,即出现“Out of Memory”。
JVM常用参数
-Xms: 初始堆大小
-Xmx:最大堆大小
-Xmn:新生代大小
-XX:NewSize=n 设置年轻代大小
-XX:NewRatio=n 设置年轻代和年老代的比值
-XX:SurvivorRatio=n 年轻代中Eden区与两个Survivor区的比值
-XX:PermSize=n 永久代(方法区)的初始大小
-XX:MaxPermSize=n 永久代大小