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收集器。

时间: 2024-10-12 20:50:04

JAVA垃圾收集器之Parallel Scavenge收集器的相关文章

JAVA垃圾收集器之Parallel Old收集器

Parallel Old收集器是JAVA虚拟机中垃圾收集器的一种.和Serial Old收集器一样,工作在JAV虚拟机的老年代.这种垃圾收集器使用多线程和"标记-整理"算法.它在JDK 1.6中才开始提供. 在注重吞吐量及CPU资源敏感的场合,都可以优先考虑Parallel Scavenge加Parallel Old收集器. 1.运行代码 package com.gc; import java.util.ArrayList; import java.util.List; /** * 简

JAVA垃圾收集器之Serial Old收集器

Serial Old收集器是JAVA虚拟机中垃圾收集器的一种,它是Serial收集器的老年代版本,它同样是一个单线程收集器,使用"标记-整理"算法.这个收集器的主要也是在目前的JAVA的Client模式下的虚拟机使用.如果在Server模式下,它主要还有两大用途:一个是在JDK 1.5及之前的版本中与Parallel Scavenge收集器搭配使用,另外一个就是作为CMS收集器的后备预案.如果CMS收集器出现Concurrent Mode Failure,则Serial Old收集器将

JVM垃圾收集器-Parallel Scavenge收集器

今天我给大家讲讲JVM垃圾收集器-Parallel Scavenge收集器 Parallel Scavenge收集器 ? ? ? ?Parallel Scavenge收集器也是一个新生代收集器,它也是使用复制算法的收集器,又是并行的多线程收集器,看上去和ParNew都一样,那它有什么特别之处呢? ? ? ??Parallel Scavenge收集器的特点是它的关注点与其他收集器不同,CMS等收集器的关注点尽可能地缩短垃圾收集时用户线程的停顿时间,而Parallel Scavenge收集器的目标是

JVM之Parallel Scavenge收集器

新生代收集器,复制算法,并行收集,面向吞吐量要求(吞吐量优先收集器). 吞吐量=用户代码运行时间/(用户代码运行时间+垃圾回收时间) -XX:MaxGCPauseMillis:控制最大垃圾收集停顿时间,大于零的毫秒数. -XX:GCTimeRatio:吞吐量大小,0到100的整数,垃圾收集时间占总时间的比例,计算1/(1+n)gc时间占用比例. -XX:UseAdaptiveSizePolicy:打开之后,就不需要设置新生代大小(-Xmn),Edian,survivor比例及(-XX:Survi

JVM垃圾收集器-Serial Old收集器,Parallel Old收集器

Serial Old收集器 ? ? ? Serial Old收集器是Serial收集器的老年代版本,它是一个单线程收集器,使用"标记-整理"算法.这个收集器的主要意义也是被Client模式下的虚拟机使用.在server模式下,它主要还有两大用途:一个是在JDK1.5及之前的版本中与Parallel Scavenge收集器搭配使用,另外一个就是作为CMS收集器的后备元,在并发收集发生 Concurrent Mode Failure的时候使用.? ? ??? ? Parallel Old收

JAVA垃圾收集器之概说

1.垃圾收集器的组合 JAVA垃圾收集器一共有7个,减去还没有正式大规模使用的G1,还有6个,其中新生代3个,老生代3个. 因为垃圾收集器都是一组一组的工作,这6个收集器一共构成了5中使用模式. 参数 描述 -XX:+UseSerialGC Jvm运行在Client模式下的默认值,打开此开关后,使用Serial + Serial Old的收集器组合进行内存回收 -XX:+UseParNewGC 打开此开关后,使用ParNew + Serial Old的收集器进行垃圾回收 -XX:+UseConc

JAVA垃圾收集器之CMS收集器

1.特点 CMS收集器是JAVA虚拟机中垃圾收集器的一种.它运行在JAVA虚拟机的老年代中.CMS是(Concurrent MarkSweep)的首字母缩写.CMS收集器是一种以获取最短回收停顿时间为目标的收集器.比较适用于互联网等场合,可能是互联网中最重要的收集器模式: 2.优点 由于整个过程中耗时最长的并发标记和并发清除过程中,收集器线程都可以与用户线程一起工作,所以总体上来说,CMS收集器的内存回收过程是与用户线程一起并发地执行的.因此CMS是一款优秀的收集器,具备了并发收集.低停顿的优点

JAVA垃圾收集器之Serial收集器

1.特点 Serial收集器是JAVA虚拟机中最基本.历史最悠久的收集器,在JDK 1.3.1之前是JAVA虚拟机新生代收集的唯一选择.Serial收集器是一个单线程的收集器,但它的"单线程"的意义并不仅仅是说明它只会使用一个CPU或一条收集线程去完成垃圾收集工作,更重要的是在它进行垃圾收集时,必须暂停其他所有的工作线程,直到它收集结束. 要是服务器每运行一个小时就会暂停5分钟,老板会有什么样的心情? 2.发展 从JDK 1.3开始,一直到现在还没正式发布的JDK 1.7,HotSpo

JAVA垃圾收集器之ParNew收集器

1.特点 ParNew收集器是JAVA虚拟机中垃圾收集器的一种.它是Serial收集器的多线程版本,除了使用多条线程进行垃圾收集之外,其余行为包括Serial收集器可用的所有控制参数(例如:-XX:SurvivorRatio.-XX:PretenureSizeThreshold.-XX:HandlePromotionFailure等).收集算法.Stop The World.对象分配规则.回收策略等都与Serial收集器一致. 2.现状 ParNew是许多运行在Server模式下的虚拟机中首选的