Serial收集器是JAVA虛擬機中最基本、歷史最悠久的收集器,在JDK 1.3.1之前是JAVA虛擬機新生代收集的唯一選擇。Serial收集器是一個,但它的“單執行緒”的意義並不僅僅是說明它只會使用一個CPU或一條收集執行緒去完成垃圾收集工作,更重要的是在它進行垃圾收集時,必須暫停其他所有的工作執行緒,直到它收集結束。
特點
Serial收集器到JDK1.7為止,它依然是
JAVA虛擬機運行在Client模式下的默認新生代收集器。它也有著優於其他收集器的地方:簡單而高效(與其他收集器的單執行緒比),對於限定單個CPU的環境來說,Serial收集器由於沒有執行緒互動的開銷,專心做垃圾收集自然可以獲得最高的單執行緒收集效率。在用戶的桌面套用場景中,分配給虛擬機管理的記憶體一般來說不會很大,收集幾十兆甚至一兩百兆的新生代(僅僅是新生代使用的記憶體,桌面套用基本上不會再大了),停頓時間完全可以控制在幾十毫秒最多一百多毫秒以內,只要不是頻繁發生,這點停頓是可以接受的。所以,Serial收集器對於運行在來說是一個很好的選擇。
固定JAVA虛擬機的大小
原始碼
package com.gc;
import java.util.ArrayList;
import java.util.List;
/**
* 簡單的JAVA虛擬機記憶體回收,serial收集器的使用
* 參數:-Xms30m -Xmx30m -Xmn10m -XX:+UseSerialGC -XX:+PrintGCDetails
* @author 范芳銘
*/
public class EasySerial {
public byte[] placeHolder = new byte[64 * 1024]; //占位符
public static void main(String[] args) throws Exception{
outOfMemoryByFixSize();
}
/**
* 固定JAVA虛擬機的大小
* 參數:-Xms30m -Xmx30m -Xmn10m -XX:+UseSerialGC -XX:+PrintGCDetails
* @author 范芳銘
*/
private static void outOfMemoryByFixSize() throws Exception{
List<EasySerial> list = new ArrayList<EasySerial>();
while(true){
EasySerial serial = new EasySerial();
list.add(serial);
Thread.sleep(10);//停頓10毫秒
}
}
/**
* JAVA虛擬機的大小適當可擴展,其中Xms30m,Xmx40m
* 參數:-Xms30m -Xmx40m -XX:+UseSerialGC -XX:+PrintGCDetails
* @author 范芳銘
*/
private static void outOfMemoryByExpansionSize() throws Exception{
List<EasySerial> list = new ArrayList<EasySerial>();
while(true){
EasySerial serial = new EasySerial();
list.add(serial);
Thread.sleep(10);//停頓10毫秒
}
}
}
參數
Xms30m -Xmx30m -Xmn10m -XX:+UseSerialGC -XX:+PrintGCDetails
-XX:+UseSerialGC的是Serial收集器,Xms30m -Xmx30m 指定了JAVA虛擬機的固定大小為30M,-Xmn10m 指JAVA新生代的空間為10M。
運行結果
[GC [DefNew: 8137K->1023K(9216K), 0.0054427 secs] 8137K->8019K(29696K), 0.0054763 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
[GC [DefNew: 9175K->963K(9216K), 0.0056574 secs] 16170K->16151K(29696K), 0.0056820 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC [DefNew: 9149K->9149K(9216K), 0.0000197 secs][Tenured: 15188K->20441K(20480K), 0.0065753 secs] 24337K->24284K(29696K), [Perm : 2086K->2086K(12288K)], 0.0066451 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
[Full GC [Tenured: 20441K->20441K(20480K), 0.0038802 secs] 29570K->29537K(29696K), [Perm : 2086K->2086K(12288K)], 0.0039147 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC [Tenured: 20441K->20436K(20480K), 0.0061865 secs] 29537K->29532K(29696K), [Perm : 2086K->2084K(12288K)], 0.0062235 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at com.gc.EasySerial.<init>(EasySerial.java:12)
at com.gc.EasySerial.outOfMemoryByFixSize(EasySerial.java:25)
at com.gc.EasySerial.main(EasySerial.java:14)
Heap
def new generation total 9216K, used 9152K [0x03bd0000, 0x045d0000, 0x045d0000)
eden space 8192K, 100% used [0x03bd0000, 0x043d0000, 0x043d0000)
from space 1024K, 93% used [0x043d0000, 0x044c00f0, 0x044d0000)
to space 1024K, 0% used [0x044d0000, 0x044d0000, 0x045d0000)
tenured generation total 20480K, used 20436K [0x045d0000, 0x059d0000, 0x059d0000)
the space 20480K, 99% used [0x045d0000, 0x059c52b8, 0x059c5400, 0x059d0000)
compacting perm gen total 12288K, used 2105K [0x059d0000, 0x065d0000, 0x099d0000)
…
GC [DefNew :是在新生代的回收,能夠很清楚的看到新生代的空間被迅速用完。
Full GC [Tenured是在老年代的全GC回收,空間也很快用完,然後出現OutOfMemoryError錯誤,導致系統崩潰。