为什么G1成为Java 9的默认垃圾收集器?

11

在Java 8之前,我们见过并行GC作为默认垃圾回收器,但是最近发布的Java版本(Java 9)将G1 GC作为默认垃圾回收器。

Java为什么改用G1 GC? 是否有性能提升?


11
在发布问题之前,你应该进行严肃的研究。 - GhostCat
4
有任何绩效改进吗?"绩效"可以用许多不同的指标来衡量。没有明确你感兴趣的指标,这个问题就变成了"为我收集信息"的领域。 - the8472
2个回答

11

摘自JEP 248(JEP - JDK Enhancement Proposal)

概述

将G1垃圾收集器设为32位和64位服务器配置的默认选择。

动机

总体上,限制GC暂停时间比最大化吞吐量更为重要。转换到低暂停的收集器如G1应该提供比当前默认的以吞吐量为导向的并行GC更好的整体使用体验。

JDK 8和其更新版本中对G1进行了许多性能改进,并计划在JDK 9中进一步改进。在JDK 8u40中引入的并发类卸载(JEP 156)使G1成为一个功能完整的垃圾收集器,已准备好成为默认选项。

简而言之,他们花费了很长时间来研究这个问题,而在Java 9中,他们终于决定把它设为默认值。


9

Oleg的答案确切地阐述了(有用的标签信息)引入背后的动机。

为什么Java转向G1 GC?是否有性能提升?

从最近在中引入的更改中学到的一些关键改进包括:

避免Full GC是与默认GC(Java 8之前使用的Parallel GC)相比的主要改进之一。

G1的目标是在不限制堆大小或活动数据量的情况下尽可能减少暂停时间。通过并发执行大部分GC工作和进行部分压缩来实现这一目标。避免执行完整的GC(即stop-the-world GC)是G1的主要优势之一。

G1在此期间的主要功能改进之一是引入了并发类卸载。此前,除了进行完整GC时,G1将所有类都视为活动的。这主要伴随着永久代的移除。

  • G1中的字符串去重

    从应用程序的角度来看,另一个特性是在G1 GC中实现自动和持续的字符串去重,以避免浪费内存并减少内存占用。这个变化伴随着String类的内部表示的更改,从UTF-16字符数组更改为byte数组加上一个编码标志字段,即紧凑字符串。

虽然如此,G1的资源使用情况与Parallel GC不同,也指出当需要最小化资源使用开销时,应该使用除G1之外的收集器,并且在此更改后,必须显式指定替代收集器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接