呃。HotSpot VM的GC组老人之一Jon Masamitsu很久之前就写过blog讲解这个:https://blogs.oracle.com/jonthecollector/entry/our_collectors

简单来说,有这么多东西反映了HotSpot VM的开发历史和实现细节。我在写篇东西讲述这部分历史,哪天写完的话在这边也放个链接嗯。

DefNewGeneration是default new generation

ParNewGeneration是parallel new generation

原本HotSpot VM里没有并行GC,当时就只有NewGeneration;后来准备要加入young gen的并行GC,就把原本的NewGeneration改名为DefNewGeneration,然后把新加的并行版叫做ParNewGeneration。

这些XXXGeneration都在HotSpot VM的“分代式GC框架”内。本来HotSpot
VM鼓励开发者尽量在这个框架内开发GC,但后来有个开发就是不愿意被这框架憋着,自己硬写了个没有使用已有框架的新并行GC,并拉拢性能测试团队用这个并行GC来跑分,成绩也还不错,于是这个GC就放进HotSpot
VM里了。这就是我们现在看到的ParallelScavenge。

(结果就是HotSpot GC组不得不维护两个功能几乎一样、但各种具体细节不同的并行GC。其实是件很头疼的事情嗯)

Scavenge或者叫scavenging GC,其实就是copying GC的另一种叫法而已。HotSpot
VM里的GC都是在minor
GC收集器里用scavenging的,DefNew、ParNew和ParallelScavenge都是,只不过DefNew是串行的copying
GC,而后两者是并行的copying GC。

由此名字就可以知道,“ParallelScavenge”的初衷就是把“scavenge”给并行化。换句话说就是把minor GC并行化。至于full GC,那不是当初关注的重点。

把GC并行化的目的是想提高GC速度,也就是提高吞吐量(throughput)。所以其实ParNew与ParallelScavenge都可叫做Throughput GC。

但是在HotSpot VM的术语里“Throughput GC”通常特指“ParallelScavenge”。

================================

ParallelScavenge和ParNew都是并行GC,主要是并行收集young gen,目的和性能其实都差不多。最明显的区别有下面几点:

1、PS以前是广度优先顺序来遍历对象图的,JDK6的时候改为默认用深度优先顺序遍历,并留有一个UseDepthFirstScavengeOrder参数来选择是用深度还是广度优先。在JDK6u18之后这个参数被去掉,PS变为只用深度优先遍历。ParNew则是一直都只用广度优先顺序来遍历

2、PS完整实现了adaptive size policy,而ParNew及“分代式GC框架”内的其它GC都没有实现(倒不是不能实现,就是麻烦+没人力资源去做)。所以千万千万别在用ParNew+CMS的组合下用UseAdaptiveSizePolicy,请只在使用UseParallelGC或UseParallelOldGC的时候用它。

3、由于在“分代式GC框架”内,ParNew可以跟CMS搭配使用,而ParallelScavenge不能。当时ParNew GC被从Exact VM移植到HotSpot VM的最大原因就是为了跟CMS搭配使用。

4、在PS成为主要的throughput GC之后,它还实现了针对NUMA的优化;而ParNew一直没有得到NUMA优化的实现。

================================

还有一点要注意:上面说ParallelScavenge并行收集young gen,那old/perm gen呢?

其实最初的ParallelScavenge的目标只是并行收集young gen,而full GC的实际实现还是跟serial
GC一样。只不过因为它没有用HotSpot VM的generational GC
framework,自己实现了一个CollectedHeap的子类ParallelScavengeHeap,里面都弄了独立的一套接口,而跟HotSpot当时其它几个GC不兼容。其实真的有用的代码大部分就在PSScavenge(=“ParallelScavenge的Scavenge”)里,也就是负责minor
GC的收集器;而负责full
GC的收集器叫做PSMarkSweep(=“ParallelScavenge的MarkSweep”),其实只是在serial
GC的核心外面套了层皮而已,骨子里是一样的LISP2算法的mark-compact收集器(别被名字骗了,它并不是一个mark-sweep收集器)。

当启用-XX:+UseParallelGC时,用的就是PSScavenge+PSMarkSweep的组合。

这是名副其实的“ParallelScavenge”——只并行化了“scavenge”。

所以其实非要说对应关系的话,PSScavenge才是真的跟ParNew对等的东西;ParallelScavenge这个名字既指代整套新GC,也可指代其真正卖点的PSScavenge。

不知道后来什么原因导致full GC的并行化并没有在原本的generational GC
framework上进行,而只在ParallelScavenge系上进行了。其成果就是使用了LISP2算法的并行版的full
GC收集器,名为PSCompact(=“ParallelScavenge-MarkCompact”),收集整个GC堆。

当启用-XX:+UseParallelOldGC时,用的就是PSScavenge+PSCompact的组合。

此时ParallelScavenge其实已经名不符实了——它不只并行化了“scavenge”(minor GC),也并行化了“mark-compact”(full GC)。

jvm垃圾收集器之Throughput GC的更多相关文章

  1. Spark(八)JVM调优以及GC垃圾收集器

    一JVM结构 1 Java内存结构 JVM内存结构主要有三大块:堆内存.方法区和栈. 堆内存是JVM中最大的一块由年轻代和老年代组成,而年轻代内存又被分成三部分,Eden空间.From Survivo ...

  2. 【转】JDK5.0中JVM堆模型、GC垃圾收集详细解析

    基本概念 堆/Heap JVM管理的内存叫堆:在32Bit操作系统上有4G的限制,一般来说Windows下为2G,而Linux下为3G:64Bit的就没有这个限制.JVM初始分配的内存由-Xms指定, ...

  3. JVM垃圾收集(Java Garbage Collection / Java GC)

    JVM垃圾收集(Java Garbage Collection / Java GC) Java7 Java8 JDK1.8之后将最初的永久代取消了,由元空间取代. 堆内存调优简介 public sta ...

  4. JVM垃圾收集器整理

    概述 垃圾收集器是jvm实现内存回收的具体实现.本次分享要介绍的7种垃圾收集器的作用区域及其之间的关系如下图: 注: 如果2个垃圾收集器之间有连线,表示可以搭配使用 垃圾收集器并没有最好的,只有针对不 ...

  5. 7种JVM垃圾收集器特点,优劣势、及使用场景

    今天继续JVM的垃圾回收器详解,如果说垃圾收集算法是JVM内存回收的方法论,那么垃圾收集器就是内存回收的具体实现. 一.常见的垃圾收集器有3类 1.新生代的收集器包括 Serial PraNew Pa ...

  6. 【006】【JVM——垃圾收集器总结】

     Java虚拟机学习总结文件夹 JVM--垃圾收集器总结 垃圾收集器概览 收集算法是内存回收的方法论.垃圾收集据是内存回收的详细实现.Java虚拟机规范中对垃圾收集器应该怎样实现没有规定.不同的厂 ...

  7. 5种JVM垃圾收集器特点和8种JVM内存溢出原因

    先来看看5种JVM垃圾收集器特点 一.常见垃圾收集器 现在常见的垃圾收集器有如下几种: 新生代收集器: Serial ParNew Parallel Scavenge 老年代收集器: Serial O ...

  8. 7种 JVM 垃圾收集器特点、优劣势及使用场景(多图)

    7种 JVM 垃圾收集器特点.优劣势及使用场景(多图)  mp.weixin.qq.com 点击上方"IT牧场",选择"设为星标"技术干货每日送达! 一.常见垃 ...

  9. JVM垃圾回收(GC)原理

    一.基本垃圾回收算法 1.引用计数(Reference Counting) 比较古老的回收算法.原理是此对象有一个引用则增加一个引用计数,删除一个引用则较少一个引用计数.垃圾回收时,只回收引用计数为0 ...

随机推荐

  1. JAVA单例MongoDB工具类

    我经常对MongoDB进行一些基础操作,将这些常用操作合并到一个工具类中,方便自己开发使用. 没用Spring Data.Morphia等框架是为了减少学习.维护成本,另外自己直接JDBC方式的话可以 ...

  2. 一个table插件,用于bootstrap开发

    最近项目中改用bootstrap,可以给的通用table,写的有点死,id名称是固定的,那一个页面两个table如何做呢? ok,模仿着别人的代码,写了一个,整体代码如下: ; (function(f ...

  3. Informatica 常用组件Source Qualifier之六 外部联接

    可以使用源限定符和应用程序源限定符转换在相同的数据库中执行两个源的外部联接.当 PowerCenter 执行外部联接时,它将返回其中一个源表的所有行和另一个源表中匹配联接条件的行. 如果您需要联接两个 ...

  4. go语言基础之运算符

    一.运算符分类 1.1 算术运算符 运算符 术语 示例 结果 + 加 10 + 5 15 - 减 10 - 5 5 * 乘 10 * 5 50 / 除 10 / 5 2 % 取模(取余) 10 % 3 ...

  5. Pycharm 2018 激活 亲测有效

    下载  https://share.weiyun.com/5NVc5U3  并将 JetbrainsCrack-3.1-release-enc.jar 放置到 pycharm安装目录的\bin目录下( ...

  6. eclipse启动tomcat, http://localhost:8080无法访问的解决方案

    问题:: tomcat在eclipse里面能正常启动,但在浏览器中访问http://localhost:8080/不能访问tomcat管理页面,且报404错误.同时其他项目页面也不能访问.访问的时候出 ...

  7. 让editplus支持sql编辑

    摘自: http://www.cnblogs.com/yeminglong/archive/2011/10/15/2212991.html 让editplus支持sql编辑 时比较喜欢用editplu ...

  8. Android面试,BroadCastReceiver的两种注册方式的异同

    在Android手机应用程序中开发中,需要用到BroadcastReceiver来监听广播的消息.在自定义好BroadcastReceiver ,需要对其进行注册,注册有两种方法: 一种是在代码当中注 ...

  9. UI设计经常使用站点

    前期:http://www.zcool.com.cn/ 中期:http://www.ui.cn/ 后期:https://dribbble.com/

  10. android-文字的处理-随心

    一.计算文字的大小 String timeStr = "00:00"; int textWidth = (int)Layout.getDesiredWidth(timeStr, 0 ...