歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Java垃圾收集器之Parallel Scavenge收集器

Parallel Scavenge收集器是JAVA虛擬機中垃圾收集器的一種。和ParNew收集器類似,是一個新生代收集器。使用復制算法的並行多線程收集器。

1、特點

Parallel Scavenge收集器的關注點與其他收集器不同, ParallelScavenge收集器的目標則是達到一個可控制的吞吐量(Throughput)。所謂吞吐量就是CPU用於運行用戶代碼的時間與CPU總消耗時間的比值,即吞吐量 = 運行用戶代碼時間 /(運行用戶代碼時間 + 垃圾收集時間),虛擬機總共運行了100分鐘,其中垃圾收集花掉1分鐘,那吞吐量就是99%。

由於與吞吐量關系密切,Parallel Scavenge收集器也經常被稱為“吞吐量優先”收集器。

      該垃圾收集器,是JAVA虛擬機在Server模式下的默認值,使用Server模式後,java虛擬機使用Parallel Scavenge收集器(新生代)+ Serial Old收集器(老年代)的收集器組合進行內存回收。

2、使用場景

主要適應主要適合在後台運算而不需要太多交互的任務。

比如需要與用戶交互的程序,良好的響應速度能提升用戶的體驗;而高吞吐量則可以最高效率地利用CPU時間,盡快地完成程序的運算任務等。

3、重要參數

重要的參數有三個,其中兩個參數用於精確控制吞吐量,分別是控制最大垃圾收集停頓時間的-XX:MaxGCPauseMillis參數及直接設置吞吐量大小的 -XX:GCTimeRatio參數。另外一個是UseAdaptiveSizePolicy開關參數。

MaxGCPauseMillis參數允許的值是一個大於0的毫秒數,收集器將盡力保證內存回收花費的時間不超過設定值。不過大家不要異想天開地認為如果把這個參數的值設置得稍小一點就能使得系統的垃圾收集速度變得更快,GC停頓時間縮短是以犧牲吞吐量和新生代空間來換取的:系統把新生代調小一些,收集300MB新生代肯定比收集500MB快吧,這也直接導致垃圾收集發生得更頻繁一些,原來10秒收集一次、每次停頓100毫秒,現在變成5秒收集一次、每次停頓70毫秒。停頓時間的確在下降,但吞吐量也降下來了。

 

GCTimeRatio參數的值應當是一個大於0小於100的整數,也就是垃圾收集時間占總時間的比率,相當於是吞吐量的倒數。如果把此參數設置為19,那允許的最大GC時間就占總時間的5%(即1 /(1+19)),默認值為99,就是允許最大1%(即1 /(1+99))的垃圾收集時間。

-XX:+UseAdaptiveSizePolicy是一個開關參數,當這個參數打開之後,就不需要手工指定新生代的大小(-Xmn)、Eden與Survivor區的比例(-XX:SurvivorRatio)、晉升老年代對象年齡(-XX:PretenureSizeThreshold)等細節參數了,虛擬機會根據當前系統的運行情況收集性能監控信息,動態調整這些參數以提供最合適的停頓時間或最大的吞吐量,這種調節方式稱為GC自適應的調節策略(GC Ergonomics)。

4、自適應調節策略

Parallel Scavenge收集器能夠配合自適應調節策略,把內存管理的調優任務交給虛擬機去完成。只需要把基本的內存數據設置好(如-Xmx設置最大堆),然後使用MaxGCPauseMillis參數(更關注最大停頓時間)或GCTimeRatio參數(更關注吞吐量)給虛擬機設立一個優化目標,那具體細節參數的調節工作就由虛擬機完成了。自適應調節策略也是Parallel Scavenge收集器與ParNew收集器的一個重要區別。

5、具體使用示例

源代碼

package com.gc;

 

import java.util.ArrayList;

import java.util.List;

 

/**

 * 簡單的JAVA虛擬機內存回收,Parallel Scavenge收集器的使用

 * 運行參數,見具體方法,注意:需要開啟server模式才能使用

 * @author 范芳銘

 */

public class EasyParallelScavenge {

      public byte[] placeHolder =new byte[64 * 1024]; //占位符

      public static voidmain(String[] args) throws Exception{

              outOfMemoryByExpansionSize();

      }

     

     

      /**

        * JAVA虛擬機的大小適當可擴展,其中Xms30m,Xmx400m

        * 參數:-server -Xms30m-Xmx100m -XX:+UseParallelGC -XX:+PrintGCDetails

        * @author 范芳銘

        */

      private static voidoutOfMemoryByExpansionSize() throws Exception{

              List<EasyParallelScavenge>list = new ArrayList<EasyParallelScavenge>();

              while(true){

                    EasyParallelScavengeserial = new EasyParallelScavenge();

                    list.add(serial);

                    Thread.sleep(10);//停頓10毫秒

              }

      }

}

參數說明:

-server  服務器模式運行

-Xms30m  最小JAVA虛擬機內存30M

-Xmx100m最大JAVA虛擬機內存100M

-XX:+UseParallelGC  明確指定使用Parallel Scavenge收集器

-XX:+PrintGCDetails 打印回收情況

 

運行結果如下:

…[GC [PSYoungGen: 7449K->3728K(7552K)] 66980K->66980K(75136K),0.0022792 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

[GC [PSYoungGen:7443K->3728K(7552K)] 70695K->70715K(75136K), 0.0027722 secs] [Times:user=0.00 sys=0.03, real=0.00 secs]

[Full GC [PSYoungGen:3728K->3136K(7552K)] [PSOldGen: 66986K->67563K(76928K)]70715K->70700K(84480K) [PSPermGen: 2088K->2088K(16384K)], 0.0038774 secs][Times: user=0.00 sys=0.00, real=0.00 secs]

[GC [PSYoungGen: 3714K->3744K(7552K)]71278K->71308K(84480K), 0.0017028 secs] [Times: user=0.00 sys=0.00,real=0.00 secs]

[GC [PSYoungGen:7459K->3744K(7552K)] 75023K->75025K(84480K), 0.0027427 secs] [Times:user=0.00 sys=0.00, real=0.00 secs]

[GC [PSYoungGen: 7459K->3744K(7552K)]78739K->78753K(84480K), 0.0048844 secs] [Times: user=0.03 sys=0.00,real=0.01 secs]

[Full GC [PSYoungGen:3744K->1728K(7552K)] [PSOldGen: 75009K->76922K(87488K)]78753K->78651K(95040K) [PSPermGen: 2088K->2088K(16384K)], 0.0107597 secs][Times: user=0.00 sys=0.00, real=0.01 secs]

[GC [PSYoungGen:3714K->3744K(7552K)] 80637K->80667K(95040K), 0.0015904 secs] [Times:user=0.00 sys=0.00, real=0.00 secs]

[GC [PSYoungGen:7459K->3728K(7552K)] 84382K->84372K(95040K), 0.0028244 secs] [Times:user=0.03 sys=0.00, real=0.00 secs]

[GC [PSYoungGen:7443K->3728K(7552K)] 88087K->88093K(95040K), 0.0023412 secs] [Times:user=0.00 sys=0.00, real=0.00 secs]

[Full GC [PSYoungGen:3728K->640K(7552K)] [PSOldGen: 84364K->87438K(91072K)]88093K->88078K(98624K) [PSPermGen: 2088K->2088K(16384K)], 0.0048474 secs][Times: user=0.00 sys=0.00, real=0.00 secs]

[Full GC [PSYoungGen:3714K->128K(7552K)] [PSOldGen: 87438K->91023K(91072K)]91153K->91151K(98624K) [PSPermGen: 2088K->2088K(16384K)], 0.0047349 secs][Times: user=0.00 sys=0.00, real=0.00 secs]

[Full GC [PSYoungGen:3714K->3714K(7552K)] [PSOldGen: 91023K->91023K(91072K)]94738K->94738K(98624K) [PSPermGen: 2088K->2088K(16384K)], 0.0031963 secs][Times: user=0.00 sys=0.00, real=0.00 secs]

[Full GC [PSYoungGen: 3714K->3649K(7552K)][PSOldGen: 91023K->91070K(91072K)] 94738K->94720K(98624K) [PSPermGen:2088K->2087K(16384K)], 0.0209529 secs] [Times: user=0.03 sys=0.00, real=0.02secs]

[Full GC [PSYoungGen:3713K->3713K(7552K)] [PSOldGen: 91070K->91070K(91072K)] 94784K->94784K(98624K)[PSPermGen: 2087K->2087K(16384K)], 0.0035128 secs] [Times: user=0.02sys=0.00, real=0.00 secs]

[Full GC [PSYoungGen:3713K->3713K(7552K)] [PSOldGen: 91070K->91070K(91072K)]94784K->94784K(98624K) [PSPermGen: 2087K->2087K(16384K)], 0.0027033 secs][Times: user=0.00 sys=0.00, real=0.00 secs]

Exception in thread "main"java.lang.OutOfMemoryError: Java heap space

    atcom.gc.EasyParNew.<init>(EasyParNew.java:12)

    atcom.gc.EasyParNew.outOfMemoryByExpansionSize(EasyParNew.java:39)

    atcom.gc.EasyParNew.main(EasyParNew.java:14)

Heap

 PSYoungGen    total 7552K, used 3776K [0x0e4b0000, 0x0efc0000, 0x0efc0000)

 eden space 3776K, 100% used [0x0e4b0000,0x0e860000,0x0e860000)

 from space 3776K, 0% used [0x0ec10000,0x0ec10000,0x0efc0000)

 to  space 3776K, 0% used[0x0e860000,0x0e860000,0x0ec10000)

 PSOldGen      total 91072K, used 91070K [0x08bc0000, 0x0e4b0000, 0x0e4b0000)

  object space 91072K, 99% used[0x08bc0000,0x0e4af980,0x0e4b0000)

 

6、和serial、parNew兩種新生代收集器的簡單區別

[GC [DefNew: 1986K->128K(2112K),0.0011191 secs] 27809K->27808K(30528K), 0.0011425 secs] [Times: user=0.00sys=0.01, real=0.00 secs]

[GC [ParNew: 1990K->132K(2112K),0.0007742 secs] 24112K->24110K(30528K), 0.0007964 secs] [Times: user=0.00sys=0.00, real=0.00 secs]

[GC [PSYoungGen:7449K->3728K(7552K)] 66980K->66980K(75136K), 0.0022792 secs] [Times:user=0.00 sys=0.00, real=0.00 secs]

GC[ParNew 表示使用的是parNew收集器。

GC[DefNew 表示用的是serial收集器。

[GC[PSYoungGen 表示用的是Parallel Scavenge收集器。

Copyright © Linux教程網 All Rights Reserved