一、簡介
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,