JAVA垃圾收集器之ParNew收集器

1、特点

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

2、现状

ParNew是许多运行在Server模式下的虚拟机中首选的新生代收集器,在JDK1.6以及之前的版本中,除了Serial收集器外,只有它能与CMS收集器配合工作。

在JDK 1.5时期,HotSpot推出了一款在强交互应用中几乎可称为有划时代意义的垃圾收集器—CMS收集器(Concurrent
Mark Sweep,本节稍后将详细介绍这款收集器),这款收集器是HotSpot虚拟机中第一款真正意义上的并发(Concurrent)收集器,它第一次实现了让垃圾收集线程与用户线程(基本上)同时工作,用前面那个例子的话来说,就是做到了在你妈妈打扫房间的时候你还能同时往地上扔纸屑。

所以在JDK 1.5中使用CMS来收集老年代的时候,新生代只能选择ParNew或Serial收集器中的一个。ParNew收集器也是使用
-XX:+UseConcMarkSweepGC选项后的默认新生代收集器,也可以使用 -XX:+UseParNewGC选项来强制指定它。

3、固定JAVA虚拟机空间

源代码:

package com.gc;

import java.util.ArrayList;

import java.util.List;

/**

* 简单的JAVA虚拟机内存回收,parNew收集器的使用

* 运行参数,见具体方法

* @author 范芳铭

*/

public class EasyParNew {

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

public static void main(String[]args) throws Exception{

outOfMemoryByFixSize();

}

/**

* 固定JAVA虚拟机的大小

* 参数:-Xms30m -Xmx30m-Xmn10m -XX:+UseParNewGC -XX:+PrintGCDetails

* @author 范芳铭

*/

private static voidoutOfMemoryByFixSize() throws Exception{

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

while(true){

EasyParNewserial = new EasyParNew();

list.add(serial);

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

}

}

/**

* JAVA虚拟机的大小适当可扩展,其中Xms30m,Xmx40m

* 参数:-Xms30m -Xmx40m-XX:+UseParNewGC -XX:+PrintGCDetails

* @author 范芳铭

*/

private static voidoutOfMemoryByExpansionSize() throws Exception{

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

while(true){

EasyParNewserial = new EasyParNew();

list.add(serial);

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

}

}

}

参数:

-Xms30m -Xmx30m -Xmn10m -XX:+UseParNewGC -XX:+PrintGCDetails

其中,-XX:+UseParNewGC
表示要强制使用parNew收集器在新生代回收空间。

运行结果:

[GC [ParNew: 8137K->980K(9216K),0.0057214 secs] 8137K->8022K(29696K), 0.0057563 secs] [Times: user=0.01sys=0.00, real=0.01 secs]

[GC [ParNew: 9131K->1021K(9216K),0.0058799 secs] 16173K->16215K(29696K), 0.0059148 secs] [Times: user=0.00sys=0.00, real=0.01 secs]

[GC [ParNew: 9207K->9207K(9216K),0.0000123 secs][Tenured: 15194K->20447K(20480K), 0.0071258 secs]24401K->24289K(29696K), [Perm : 2086K->2086K(12288K)], 0.0071911 secs][Times: user=0.00 sys=0.00, real=0.01 secs]

[Full GC [Tenured:20447K->20447K(20480K), 0.0038141 secs] 29576K->29543K(29696K), [Perm :2086K->2086K(12288K)], 0.0038490 secs] [Times: user=0.00 sys=0.00, real=0.00secs]

[Full GC [Tenured:20447K->20436K(20480K), 0.0063466 secs] 29543K->29532K(29696K), [Perm :2086K->2084K(12288K)], 0.0063865 secs] [Times: user=0.00 sys=0.00, real=0.01secs]

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

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

atcom.gc.EasyParNew.outOfMemoryByFixSize(EasyParNew.java:25)

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

Heap

par new generation   total 9216K, used 9152K [0x03c10000,0x04610000, 0x04610000)

eden space 8192K, 100% used [0x03c10000, 0x04410000, 0x04410000)

from space 1024K,  93% used[0x04410000, 0x045000f0, 0x04510000)

to   space 1024K,   0% used [0x04510000, 0x04510000, 0x04610000)

tenured generation   total 20480K, used 20436K [0x04610000,0x05a10000, 0x05a10000)

the space 20480K,  99% used [0x04610000, 0x05a052b8, 0x05a05400,0x05a10000)

4、可扩展的JAVA虚拟机空间

使用源代码中对应的outOfMemoryByExpansionSize方法和配套的参数。

运行结果如下:

[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 [ParNew: 1990K->130K(2112K),0.0008112 secs] 25969K->25965K(30528K), 0.0008477 secs] [Times: user=0.00sys=0.00, real=0.00 secs]

[GC [ParNew: 1988K->130K(2112K),0.0009319 secs] 27823K->27821K(30528K), 0.0009553 secs] [Times: user=0.00sys=0.00, real=0.00 secs]

[GC [ParNew: 1991K->134K(2112K),0.0008219 secs][Tenured: 29548K->29551K(29568K), 0.0031503 secs] 29682K->29679K(31680K),[Perm : 2086K->2086K(12288K)], 0.0040531 secs] [Times: user=0.01 sys=0.00,real=0.00 secs]

[GC [ParNew: 2562K->194K(2880K),0.0024877 secs] 32113K->32113K(40704K), 0.0025124 secs] [Times: user=0.00sys=0.00, real=0.00 secs]

[GC [ParNew: 2756K->196K(2880K),0.0010854 secs] 34676K->34680K(40704K), 0.0011096 secs] [Times: user=0.00sys=0.00, real=0.00 secs]

[GC [ParNew: 2758K->196K(2880K),0.0011059 secs] 37243K->37241K(40704K), 0.0011285 secs] [Times: user=0.03sys=0.00, real=0.00 secs]

[GC [ParNew: 2758K->2758K(2880K),0.0000123 secs][Tenured: 37045K->37813K(37824K), 0.0037394 secs]39803K->39798K(40704K), [Perm : 2086K->2086K(12288K)], 0.0037977 secs][Times: user=0.00 sys=0.00, real=0.00 secs]

[Full GC [Tenured:37813K->37813K(37824K), 0.0034278 secs] 40569K->40567K(40704K), [Perm :2086K->2086K(12288K)], 0.0034685 secs] [Times: user=0.00 sys=0.00, real=0.00secs]

[Full GC [Tenured:37813K->37792K(37824K), 0.0107084 secs] 40567K->40546K(40704K), [Perm :2086K->2084K(12288K)], 0.0107696 secs] [Times: user=0.01 sys=0.00, real=0.01secs]

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

par new generation   total 2880K, used 2810K [0x03bf0000,0x03f00000, 0x03f00000)

eden space 2624K,  99% used[0x03bf0000, 0x03e7e8e8, 0x03e80000)

from space 256K,  75% used[0x03ec0000, 0x03ef0030, 0x03f00000)

to   space 256K,   0% used [0x03e80000, 0x03e80000, 0x03ec0000)

tenured generation   total 37824K, used 37792K [0x03f00000,0x063f0000, 0x063f0000)

the space 37824K,  99% used[0x03f00000, 0x063e82e0, 0x063e8400, 0x063f0000)

compacting perm gen  total 12288K, used 2105K [0x063f0000,0x06ff0000, 0x0a3f0000)

the space 12288K,  17% used [0x063f0000, 0x065fe4a8, 0x065fe600,0x06ff0000)

5、ParNew收集器和Serial收集器的差异

ParNew收集器在单CPU的环境中绝对不会有比Serial收集器更好的效果,甚至由于存在线程交互的开销,该收集器在通过超线程技术实现的两个CPU的环境中都不能百分之百地保证能超越Serial收集器。当然,随着可以使用的CPU的数量的增加,它对于GC时系统资源的利用还是很有好处的。它默认开启的收集线程数与CPU的数量相同,在CPU非常多(譬如32个,现在CPU动辄就4核加超线程,服务器超过32个逻辑CPU的情况越来越多了)的环境下,可以使用-XX:ParallelGCThreads参数来限制垃圾收集的线程数。

并行(Parallel):指多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态。

并发(Concurrent):指用户线程与垃圾收集线程同时执行(但不一定是并行的,可能会交替执行),用户程序继续运行,而垃圾收集程序运行于另一个CPU上。

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

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

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

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

时间: 2024-08-01 08:53:03

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

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垃圾收集器之Parallel Scavenge收集器

Parallel Scavenge收集器是JAVA虚拟机中垃圾收集器的一种.和ParNew收集器类似,是一个新生代收集器.使用复制算法的并行多线程收集器. 1.特点 Parallel Scavenge收集器的关注点与其他收集器不同, ParallelScavenge收集器的目标则是达到一个可控制的吞吐量(Throughput).所谓吞吐量就是CPU用于运行用户代码的时间与CPU总消耗时间的比值,即吞吐量 = 运行用户代码时间 /(运行用户代码时间 + 垃圾收集时间),虚拟机总共运行了100分钟,

JVM垃圾收集器-ParNew收集器

今天我给大家讲讲ParNew收集器. ParNew收集器 ParNew收集器收集器其实就是Serial收集器的多线程版本,除了使用多线程进行垃圾收集之外,其余行为包括Serial收集器可用的所有控制参数.收集算法.Stop The world.对象分配规则.回收策略等都与Serial收集器完全一样,实现上这两种收集器也共用了相当多的代码.ParNew收集器的工作过程如下图所示. ParNew收集器除了多线程收集之外,其他与Serial收集器相比并没有太多创新之处,但它却是许多运行在Server模

Java垃圾收集器之--Garbage-First Collector

简介       Garbage-First(G1)垃圾收集器全面支持JDK7 Upate 4及后续版本.G1收集器是一个服务器形式(server-style)的垃圾收集器,主要用于内存大.多处理器的机器.当您想实现:与应用程序线程并发的执行全局标记,并且有高吞吐量.面向整个堆操作时,它可以满足您高可用性及GC暂停时间的要求. 此举可有效防止中断(GC时的暂停时间)与堆或者实时数据大小成比例增涨. 技术 G1收集器通过如下技术来实现高性能和低暂停时间: 堆被划分成一组相同大小的堆区域(heap

JVM快速调优手册之五: ParNew收集器+CMS收集器的产品案例分析(响应时间优先)

服务器 双核,4个cores; 16G memory [[email protected] ~]# cat /proc/cpuinfo | grep "cpu cores" cpu cores : 2 cpu cores : 2 公式简述 响应时间优先的并发收集器,主要是保证系统的响应时间,减少垃圾收集时的停顿时间.适用于应用服务器.电信领域等. ParNew收集器 ParNew收集器是Serial收集器的多线程版本,许多运行在Server模式下的虚拟机中首选的新生代收集器,除Seri

ParNew收集器

ParNew收集器其实就是Serial收集器的多线程版本,除了使用多条线程进行垃圾收集之外,其余行为包括Serial收集器可用的所有控制参数,其中Par是Paralle简写l 并行(Parallel):指多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态. 并发(Concurrent):指用户线程与垃圾收集线程同时执行(但不一定是并行的,可能会交替执行),用户程序在继续运行,而垃圾收集程序运行于另一个CPU上.

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

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

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; /** * 简