OpenJDK 8 有多种 GC(Garbage Collector)算法,如 Parallel GC、CMS 和 G1。哪一个才是最快的呢?如果在 Java 9 中将 Java 8 默认的 GC 从 Parallel GC 改为 G1 (目前只是建议)将会怎么样呢?让我们对此进行基准测试。

基准测试方法

运行相同的代码六次,每次使用不同的VM参数(-XX:+UseSerialGC, -XX:+UseParallelGC, -XX:+UseConcMarkSweepGC, -XX:ParallelCMSThreads=2, -XX:ParallelCMSThreads=4, -XX:+UseG1GC)。

每次运行大概花费55分钟。

其它VM参数:-Xmx2048M -server

OpenJDK版本:1.8.0_51(当前最新的版本)

软件:Linux version 4.0.4-301.fc22.x86_64

硬件:Intel? Core? i7-4790 CPU @ 3.60GHz

每次运行13个?OptaPlanner?规划问题方案。每次运行时间为5分钟。前30秒用于JVM预热,不计算在内。

解决规划问题不涉及 IO (除了启动时需要几毫秒来加载输入信息)。单个 CPU 使用完全饱和。通常会创建许多存活时间很短的对象,GC 之后就会回收这些对象。

衡量标准可以是计算每毫秒的得分,越高越好。计算一个拟议规划解决方案是一个不可小觑的问题:涉及到大量的计算,包括每个实体与其他所有实体的冲突检测。

为了能在本地重复运行这些基准测试,可以从源码进行构建,然后运行主类 GeneralOptaPlannerBenchmarkApp。

基准测试结果

执行结果

为了方便查看,我已经对每种 GC 与 Java 8 默认 GC(Parallel GC)进行了比较。

结果非常清楚:默认(Parallel GC)是最快的

原始基准测试数据

相对基准测试数据

Java 9 默认应该为 G1 吗?

有一种提议是在 OpenJDK9 的服务器端使用 G1 作为默认 GC。我第一反应就是拒绝该提议:

G1 的平均值要慢17.60%

G1 在每个数据集用例下都比较慢。

在最大数据集(Machine Reassignment B10)下,表现比其它数据集都要差,G1 慢了34.07%。

如果在开发机和服务器之间采用不同的默认 GC,则开发者基准测试的可信度就会下降。

另一方面,存在几个需要注意的细节:

G1 关注是 GC 暂停的问题,而不是吞吐量。对于这些用例(计算量比较大),GC 暂停时长基本没影响。

这是一个(基本是)单线程的基准测试。并行解决多个问题或采用多线程解决的基准测试,结果可能不同。

G1 推荐的堆内存至少是 6GB。而这次基准测试的堆内存是 2GB,即使在最大数据集(Machine Reassignment B10)也只需要这么多内存。

海量计算只是 OpenJDK 的诸多功能中的一个:这是在社区广泛争论的一个问题。如果有其他方面(如网站服务)的证明,可能值得改变默认GC。但是,请首先向我展示你实际项目的基准测试。

结论

在 Java 8 中,对 OptaPlanner 用例来说,默认 GC(Parallel GC)通常情况是最好的选择。

原文链接: javacodegeeks 翻译: ImportNew.compaddx
译文链接: http://www.importnew.com/16533.html
转载请保留原文出处、译者和译文链接。]

Java 8最快的垃圾收集器是什么?的更多相关文章

  1. 深入理解Java虚拟机 第三章 垃圾收集器 笔记

    1.1   垃圾收集器 垃圾收集器是内存回收的具体实现.以下讨论的收集器是基于JDK1.7Update14之后的HotSpot虚拟机.这个虚拟机包含的所有收集器有: 上图展示了7种作用于不同分代的收集 ...

  2. 深入理解java虚拟机(五)垃圾收集器

    垃圾收集器 垃圾收集器是垃圾收集算法的具体实现.Java规范对垃圾收集器的实现没有做任何规定,因此不同的虚拟机提供的垃圾收集器可能有很大差异.HotSpot虚拟机1.7版本使用了多种收集器.如下图. ...

  3. <<深入Java虚拟机>>-第三章-垃圾收集器与内存分配策略-学习笔记

    垃圾收集 垃圾收集(Garbage Collection,GC),垃圾收集需要完成的三件事情. 哪些对象需要回收 什么时候回收 如何回收 如何确定对象已死(即不可能在被任何途径引用的对象) 引用计数算 ...

  4. 深入了解Java虚拟机(2)垃圾收集器与内存分配策略

    垃圾收集器与内存分配策略 由于JVM中对象的频繁操作是在堆中,所以主要回收的是堆内存,方法区中的回收也有,但是比较谨慎 一.对象死亡判断方法 1.引用计数法 就是如果对象被引用一次,就给计数器+1,否 ...

  5. 《深入理解Java虚拟机》笔记03 -- 垃圾收集器

    收集器可以大致分为:单线程收集器, 并发收集器和并行收集器. 并行(Parallel):指多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态. 并发(Concurrent):指用户线程与垃圾收集 ...

  6. Java垃圾回收之新生代垃圾收集器

    问题:什么是Stop-the-World? 1.JVM由于要执行GC而停止了应用程序的执行 2.任何一种GC算法中都会发生 3.多数GC优化通过减少Stop-the-world发生的时间来提高程序的性 ...

  7. 《深入理解Java虚拟机》读书笔记-垃圾收集器与内存分配策略

    在堆里存放着java世界中几乎所有的对象实例,垃圾收集器在对堆进行回收前需要知道哪些对象还存活,哪些对象已经死去.那怎么样去判断对象是否存活呢? 一.判断对象是否存活算法 1.引用计数法 实现思路:给 ...

  8. Java虚拟机的内存管理----垃圾收集器

    1.Serial收集器 优点,是简单而高效,单线程避免了线程交互的开销. 缺点,进行垃圾回收时需要Stop the world(暂停所有用户线程). 2.ParNew收集器 它是Serial收集器的多 ...

  9. java垃圾回收算法和垃圾收集器

    垃圾收集算法.垃圾回收算法.java垃圾收集器 目录1. 垃圾收集算法1)引用计数法2)根搜索法2. 垃圾回收算法1)复制算法2)标记-清除算法3)标记-整理算法4)分代收集算法3. java垃圾收集 ...

随机推荐

  1. 19-11-13-Night-∠

    连夜补博客 ZJ: 看见T1就自闭了.(高考数学)(但是好像不是) 三个暴力就结束了. 35 Miemeng 20 00:00:41 10 00:00:41 10 00:00:41 40 00:00: ...

  2. JS里面function和Function的区别

    js里Function 与 function的不一样的,不仅仅是大小写的问题. 简单点说:大写的Function是一个类 ,而小写的function是一个对象. Function是一个构造器,func ...

  3. Jmeter性能测试(第三篇)

    一.调通脚本(以json串Post接口为例)添加聚合报告(线程组->添加->监听器->聚合报告)并调试好需要压测的脚本,如下已经调通的P_C_B151就是我需要压测的脚本 二.设置场 ...

  4. C++【stack/queue】用法和例子

    Stack的常用基本操作: s.push() // 压栈 s.emplace() // 插入,相当于push(目前掌握的唯一区别是emplace可以自行调用构造函数,push不行) s.empty() ...

  5. windows API 第 18篇 FindFirstVolume FindNextVolume

    函数定义:Retrieves the name of a volume on a computer. FindFirstVolume is used to begin scanning the vol ...

  6. 最小费用最大流——ZKW

    对于最小费用最大流,我们的通常做法是EK+SPFA. 然而,卡常界大佬ZKW发明了一个求解最小费用最大流的方法,很强啊. 在学ZKW费用流前,先说说KM算法. KM算法 为啥要先提这个呢?因为ZKW费 ...

  7. HZOI20190823 C magic

    数论板子合集... 我们要求: $N^{\sum\limits_{i=1}^{N}[gcd(i,N)==1]C_{n}^{i}}mod p$ 其中p为54184622,是个合数 指数是组合数,不能用快 ...

  8. HZOI20190821模拟28题解

    题面:https://www.cnblogs.com/Juve/articles/11390839.html 所有官方正解在我的文件里 A. 虎 算法1:我们发现非关键边与黑色边去掉以后,答案就是将所 ...

  9. kill 3000

    杀3000端口,是作为一个web未开发人员经常遇到的事情 所以我今天就分享一下我的杀3000端口秘诀 lsof -i: 先要找到端口 node zcool 20u IPv6 0xdddbb4f6f12 ...

  10. 深入浅出 Java Concurrency (8): 锁机制 part 3[转]

    接上篇,这篇从Lock.lock/unlock开始.特别说明在没有特殊情况下所有程序.API.文档都是基于JDK 6.0的. public void java.util.concurrent.lock ...