标签:
JVM采用分代垃圾回收。在JVM的内存空间中把堆空间分为年老代和年轻代。将大量(据说是90%以上)创建了没多久就会消亡的对象存储在年轻代,而年老代中存放生命周期长久的实例对象。年轻代中又被分为Eden区(圣经中的伊甸园)、和两个Survivor区。新的对象分配是首先放在Eden区,Survivor区作为Eden区和Old区的缓冲,在Survivor区的对象经历若干次收集仍然存活的,就会被转移到年老区。
简单讲,就是生命期短的对象放在一起,将少数生命期长的对象放在一起,分别采用不同的回收策略。生命期短的对象回收频率比较高,生命期长的对象采用比较低回收频率,生命期短的对象被尝试回收几次发现还存活,则被移到另外一个地方去存起来。就像现在夏天了,勤劳的douma把doudou和douba常穿的衣服放在顺手的地方,把冬天的衣服打包放在柜子另一个地方。虽然把doudou的小衣服类比成虚拟机里的对象有点不合适,大致意思应该就是这样。
本文中通过最简单的一个例子来demo下这个过程,代码很短,很简单,希望剖析的细一点,包括每一步操作后对象的分配和回收对内存堆产生的影响。设定上包括对堆中年轻代(年轻代中eden区和survivor区)、年老代大小的设定,以及设置阈值控制年轻代到年老代的晋升。
下面是最简单的代码,通过代码的每一步的执行来剖析其中的规则。
package com.idouba.jvm.demo;
/**
* @author idouba
* Use shortest code demo jvm allocation, gc, and someting in gc.
*
* In details
* 1) sizing of young generation (eden space,survivor space),old generation.
* 2) allocation in eden space, gc in young generation,
* 3) working with survivor space and with old generation.
*
*/
public class SimpleJVMArg {
/**
* @param args
*/
public static void main(String[] args)
{
demo();
}
/**
* VM arg:-verbose:gc -Xms200M -Xmx200M -Xmn100M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=1 -XX:+PrintTenuringDistribution
*
*/
@SuppressWarnings("unused")
public static void demo() {
final int tenMB = 10* 1024 * 1024;
byte[] alloc1, alloc2, alloc3;
alloc1 = new byte[tenMB / 5];
alloc2 = new byte[5 * tenMB];
alloc3 = new byte[4 * tenMB];
alloc3 = null;
alloc3 = new byte[6 * tenMB];
}
}
通过jvm 参数设定几个区域的大小,结合代码执行可以观察到对象在堆上分配和回收的过程。执行参数如下:
-verbose:gc -Xms200M -Xmx200M -Xmn100M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:+PrintTenuringDistribution
通过设这-Xms200M -Xmx200M 设置Java堆大小为200M,不可扩展,-Xmn100M设置其中100M分配给新生代,则200-100=100M,即剩下的100M分配给老年代。-XX:SurvivorRatio=8设置了新生代中eden与survivor的空间比例是1:8。
执行上述代码结果如下:
[GC [DefNew
Desired survivor size 5242880 bytes, new threshold 15 (max 15)
- age 1: 2237152 bytes, 2237152 total
: 54886K->2184K(92160K), 0.0508477 secs] 54886K->53384K(194560K), 0.0508847 secs] [Times: user=0.03 sys=0.03, real=0.06 secs]
[GC [DefNew
Desired survivor size 5242880 bytes, new threshold 15 (max 15)
- age 2: 2237008 bytes, 2237008 total
: 43144K->2184K(92160K), 0.0028660 secs] 94344K->53384K(194560K), 0.0028957 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
Heap
def new generation total 92160K, used 65263K [0x1a1d0000, 0x205d0000, 0x205d0000)
eden space 81920K, 77% used [0x1a1d0000, 0x1df69a10, 0x1f1d0000)
from space 10240K, 21% used [0x1f1d0000, 0x1f3f2250, 0x1fbd0000)
to space 10240K, 0% used [0x1fbd0000, 0x1fbd0000, 0x205d0000)
tenured generation total 102400K, used 51200K [0x205d0000, 0x269d0000, 0x269d0000)
the space 102400K, 50% used [0x205d0000, 0x237d0010, 0x237d0200, 0x269d0000)
compacting perm gen total 12288K