(2008年2月1日。翻译自https://blogs.oracle.com/jonthecollector/our-collectors。文章比较早,主要对比了ParNew和Paraller Scavenge之间的不同和相同点)
    前段时间,我在给朋友讲解的时候,在白板上画了下面这个图。他们看起来(也许只是表现得)很喜欢,因此我想再给你们画一次。

    每一个蓝色的盒子代表了一种用来分代回收的算法。在黄色区域中代表的是新生代被各种蓝色盒子代表的算法回收,下面的灰色区域中则是老年代被各种盒子代表的算法回收。
    “Serial”是一种需要STW的复制回收算法,它使用的是单线程回收。
    “ParNew”也是一种需要STW的复制回收算法,但是它使用多线程进行回收。它与”Parallel Scavenge”不同的地方在于,为了能让它和CMS适用,它做了一些增强。例如,它做了一些必要的同步以便在CMS的并发回收的时候,它也能运行。
    “Paraller Scavenge”也是一个需要STW的多线程的复制算法。
    “Serial Old”是一个需要STW的标记整理算法,它使用的是单线程。
    “CMS”是一个在大多数时候并发,停顿时间低的回收器。
    “Parallel Old”是一个标记整理回收器,使用的是多线程。

在jdk6中,使用-XX参数来管理我们的回收器。

使用SerialGC是用”Serial”+”Serial Old”
    使用ParNewGC是用“ParNew”+”Serial Old”
    使用CMS是用“ParNew”+”CMS”+”Serial Old”.在大多数情况下,都使用CMS来回收老年代。“Serial Old”则是在当发生一个concurrent mode failure的时候用的。
    使用ParallelGC是“Paraller Scavenge”+”Serial Old”
    使用ParallelOldGC是“Parallel Scavenge”+”Paraller Old”

FAQ

(1)使用ParNew 和ParallerGC都是使用多线程回收新生代,哪个更快?
    答:这个问题没有正确答案。在大多数情况下,他们都表现的不错。但是在不同的场景下其中一个回收器会比另外一个更好。如果你想使用GC ergonomics(堆各分代大小动态调整),那只能用ParallelGC(和ParallelOldGC)。
    (2)为什么“ParNew”和“Parallel Old”不能一起使用?
    答:“ParNew”是在一个框架的基础上写的,在这个框架中,每一个即将被回收的分代都为回收提供了确定的接口。例如,“ParNew”和“Serial”实现了space_iterate()接口。这个接口为这个新生代中的每一个对象都添加了一个方法。当用CMS或者是Serail Old来回收老年代的时候,GC可以使用space_iterate()来为这些在新生代中的对象做一些工作。这使得回收器的混合-匹配起作用,但是为了维持回收器和增加新的回收器增加了负担。而且这个负担看起来是回收器数量的2次方。
    另外,“Parallel Scavenge”(至少在Parallel Old之前的最开始的实现中)总是知道老年代是怎样被收集的,而且可以直接调用Serail Old回收器中的代码。
    顺便提一句,我们想要将Parallel Scavenge和Parallel Old搭配使用,而且会清理任何Paraller Scavenge需要的代码,以便2者能够同时使用。
    不需要对上面我提到的例子思考太多。他们不值得你浪费时间。

(3)我怎么使用CMS和Serial?
    -XX:+UseConcMarkSweepGC -XX:-UseParNewGC.
    不要使用-XX:+UseConcMarkSweepGC和-xx:+UseSerialGC.虽然他们看起来是一个逻辑组合,但是这会导致回收器冲突,JVM无法启动。
    (4)图上”?”的蓝色盒子是一个输入错误?
    它代表了我们正在开发的一种新的垃圾回收类型,我们称为G1.G1会提供:
    1.更加可预测的GC暂停。
    2.更好的GC自适应调整
    3.更低的暂停且没有内存碎片
    4.并行和并发的回收
    5.更好的堆利用率
    G1对新生代和老年代没有明显的界限,因为它只是逻辑上的分代回收。G1把堆分成一个个区域,然后在一次回收过程中,可以回收区域的一个子集。说它是逻辑上的分代,是因为它会动态的选择区域的一个集合作为一个新生代一样在下次被回收(就像新生代一样)。用户可以设置暂停时间的目标,然后G1会基于过去的回收做一个分析,看多少区域可以在这个暂停时间内回收。这些区域成为一个垃圾集合,G1会在下次进行回收。
    G1可以选择首先对垃圾最多的区域进行回收(知道为什么叫garbage first了没?)
    堆不会静态的被分割为一个新生代和一个老年代,所以他们之间容量大小的平衡在这里不是个问题。
    除了设置停顿时间外,还可以设置在某一个阶段中消耗的GC时间(比如设置在接下来的100秒中垃圾回收时间小于10秒)。为了达到这样的目标,G1可以选择一个回收器能花费小于10s就能回收完成的垃圾集合,从之前的回收中提前计划好90s的时间。
    你可以看到在下一个时代中一个用户可以设置0秒的回收时间,这还只是目标而已,不是承诺。

如果G1运行的符合我们的期望,它会代替ParNew+CMS而成为我们的低停顿的回收器。如果你想问它什么时候会开发完成,请不要为我死后的沉默冒犯。这个是我们团队最高优的项目,但是这是软件开发,所以常常会有一些未知的因素。它会在jdk7中推出。就我们而言,越早越好。

2月4号更新。我已经可以重新编辑已经发布的博客,如果你有ACM门户的访问权限,这里是一篇G1论文的链接。
    http://portal.acm.org/citation.cfm?id=1029879

Our Collectors相关推荐

  1. java8 group by_java8新特性Java 8 – Stream Collectors groupingBy 示例 - Java教程

    在这篇教程中,将向你展示如何使用Java 8 Stream的Collectors,来对一个List进行分组,计算个数,求和以及排序. 1. Group By, Count and Sort 1.1 对 ...

  2. collectors排序_Collectors.groupingBy分组后的排序问题

    默认groupingBy代码里会生成一个HashMap(hashMap是无序的,put的顺序与get的顺序不一致) HashMap是无序的,HashMap在put的时候是根据key的hashcode进 ...

  3. js 中转换成list集合_java stream中Collectors的用法

    简介 在java stream中,我们通常需要将处理后的stream转换成集合类,这个时候就需要用到stream.collect方法.collect方法需要传入一个Collector类型,要实现Col ...

  4. java 返回double数组_java-如何使用Collectors.averagingDouble计算双精度数组的均值?

    我不明白为什么以下代码无法编译: import java.util.Arrays; import java.util.stream.Collectors; public class AppMain { ...

  5. Stream流与Lambda表达式(三) 静态工厂类Collectors

    /*** @author 陈杨*/@SpringBootTest @RunWith(SpringRunner.class) public class CollectorsDetail {private ...

  6. Java 8 - 收集器Collectors

    文章目录 Pre 简介 收集器用作高级归约 预定义收集器 Pre 我们前面学到了,流可以用类似于数据库的操作帮助你处理集合. 它们支持两种类型的操作: 中间操作(如 filter 或 map ) 终端 ...

  7. 【备忘录】Product cost collectors – 成本收集器

    以生产角度来划分: 流程制造 - Product Cost by Period 离散制造 - Product Cost by Period & Product Cost by Order 这里 ...

  8. java 相加的函数_Java8 Collectors求和功能的自定义扩展操作

    业务中需要将一组数据分类后收集总和,原本可以使用Collectors.summingInt(),但是我们的数据源是BigDecimal类型的,而Java8原生只提供了summingInt.summin ...

  9. 用流收集数据Collectors的用法介绍分组groupingBy、分区partitioningBy(一)

    文章目录 一.收集器简介 二.归约和汇总 1.查找流中最大值和最小值Collectors.maxBy和,Collectors.minBy 2.汇总 3.连接字符串 4.广义归约汇总 三.分组 1.多级 ...

  10. 【Java代码】实现字符串转数据库的 inStr【使用 JDK8 stream.collect(Collectors.joining(delimiter, prefix, suffix)) 实现】

    why 有不少这样的情况,前端会传筛选条件,给到后端的时候是个 conditionStr ,如果您用的是 mybatis-plus 的 API 那么直接 split 一下就可以使用,如果不是,那就需要 ...

最新文章

  1. 神策数据 App 可视化全埋点 2.0 重磅升级!抢先体验
  2. elasticsearch mapping之fields
  3. icewm使用心得[转]
  4. java 运行管理-基础
  5. 1.Office 365系列(-)
  6. es文件管理复制到fpt服务器,达人教你玩应用:ES文件浏览器之文件互传
  7. 爬取《NBA30支球队》“现役球员信息”,分别存储到3种不同的数据库!
  8. Microsoft store 无法联网,显示Microsoft Store需要联网,你似乎没有联网
  9. mac电脑怎么连接蓝牙鼠标?
  10. docker使用docker compose file部署项目时,实现容器卷挂载,并对容器内文件夹赋予权限
  11. 2.3 连续性随机变量
  12. java点打印没反应_兄弟QL打印机SDK - 不打印,没有任何反应(QL-710W)
  13. oracle v backup,睿备份oracle下载
  14. 谷歌地球如何下载使用高程数据
  15. 深蹲的26种变化动作(深蹲大全)
  16. dancer配置问题集合
  17. 【图像融合】小波变换彩色图像融合(带面板)【含GUI Matlab源码 782期】
  18. 跨学科协同,第四届PLAGH-MIT医疗大数据学术交流及Datathon活动圆满落幕
  19. 如何root安卓手机_一个手机不够用?安卓模拟器vmos虚拟大师自带root
  20. 年终反思 -- 系统学习心理学之后对学习生活的感悟【再见2022,你好2023】

热门文章

  1. element-vue+echarts 竖状树形图,组织机构图组合
  2. 前端面试——跨域问题
  3. 35、查询所有学生的课程及分数情况(重点)
  4. Jmeter测试计划元件+后置处理器元件+执行顺序
  5. MySql 获取年月日 时分秒、年月日、年月、年、月
  6. 2020生活性服务业就业指数报告-58同城-2021
  7. 我见很多赚大钱的人,但没有一个是靠努力成功的!(强烈推荐)
  8. 损失函数loss大总结
  9. cocos2d Armature
  10. HBCPC2021-河北省大学生程序设计竞赛-部分题解