天天看點

最簡單例子圖解JVM記憶體配置設定和回收

一、簡介

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,