`
ivywang
  • 浏览: 33324 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

HotSpot JVM里的G1垃圾收集器

阅读更多

G1垃圾收集器

HotSpot JDK 7从update 4开始引入了G1垃圾收集器。

G1收集器是服务器风格的垃圾回收器,主要针对多处理器机器上占用大量内存的应用。G1能缩短暂停时间,也能提供高吞吐量。

与CMS的区别

和CMS(Concurrent Mark-Sweep)收集器相比,G1具备压缩功能,能避免碎片问题;G1的暂停时间更加可控,用户可以指定暂停时间指标。

以前的垃圾收集器(顺序、并行、CMS)都把堆分为三个部分:年轻代、老年代、永久代,三个部分的大小都是固定的。而在G1里,堆被分为若干区域,每个区域里的内存是连续的。区域会有“角色”,但某个“角色”的大小并不固定,这就提供了更大的内存使用灵活度。


执行垃圾回收的时候,G1的操作和CMS有些类似,G1也会和应用并行地进行全局标记。标记阶段结束后,G1会优先收集存活对象少(占用空间小)的区域,也就是垃圾(可回收对象)多的区域。G1采用“pause prediction模型”,根据用户定义的暂停时间指标确定回收区域的个数。

G1要回收的区域会被清空,里面的存活对象会被拷贝到堆里的另一个单独区域,压缩、释放原区域里的内存。在多处理器机器上,这会并行地执行,减少暂停时间、增加吞吐量。

但G1不是实时收集,它会基于前面收集的相关数据进行评估,看在用户指定的暂停时间里能收集几个区域。

 

G1里有两个数据结构:

  • Remembered Sets(RSets):每个堆区域都有一个RSet,记录该区域里的对象引用。有了RSet,就可以对区域进行并行、独立的收集。
  • Collection Sets(CSets):GC要收集的区域集合,集合里的区域可以是任意角色(Eden、Survivor或老年代)。CSet里记录的区域都会被清空(回收掉或者移走)。

适用场景

G1适合堆大小差不多是6GB或者更大,暂停时间要求在0.5秒以下的场景。如果应用具备如下一个或多个特征用G1会有比较好的效果:

  • Full-GC执行太频繁,或者持续的时间太长
  • 对象分配的速度差距较大
  • 不希望GC暂停时间超过0.5-1秒

但如果应用或系统的GC暂停时间本来就不长,建议还是保持原先的GC,不要换成G1

工作步骤

堆被划分为很多区域,区域大小由JVM确定(用户也可以设置),通常是1MB-32MB,大约2000个。

区域会具备“Eden”、“Survivor”、“老年代”的角色,但它们不是连续的。还有另外一种区域,叫Humongous区域,它用来存放大对象(大小超过区域大小的50%),这些区域是连续的。

年轻代

存活对象会被拷贝/移动到一个或多个“Survivor”区域,存活时间够长的直接移到“老年代”区域。这里会stop the world,但young GC的过程是多线程执行的。

老年代

1、初始标记(stop the world):标记引用老年代里对象的Survivor区域,这些Survivor区域叫root区域     GC pause (young)(inital-mark)

2、扫描root区域:扫描survivor区域,找到引用老年代里内容的对象。young GC开始前要完成。

3、并发标记:找出整个堆里可达的对象,计算各个区域的对象存活率。这个阶段可能会被年轻代的GC中断。

4、Remark(stop the world):对并发标记阶段的结果查漏补缺,使用snapshot-at-the-beginning(SATB)算法,比CMS使用的算法快很多;而且会回收空区域(没有存活对象的区域)

5、清理:先stop the world,收集对象存活率最低的区域,然后清理Remembered Set。接着应用可以运行了,这时会重置空闲区域,并将这些区域返回给free list。年轻代和老年代同时回收

6、拷贝(stop the world):将存活对象拷贝到没有使用的区域里

命令行选项

G1可用的命令行选项有:

-XX:+UseG1GC——让JVM使用G1垃圾回收器

-XX:MaxGCPauseMillis=200——设置GC暂停时间目标值,缺省200毫秒。但这不是硬指标,JVM会尽力满足。

-XX:InitiatingHeapOccupancyPercent=45——整个堆被占用多少之后开始进行GC,缺省为45,0表示持续不停进行GC

-XX:NewRatio=n——年轻代和老年代的比例,缺省为2

-XX:SurvivorRatio=n——Eden和Survivro的比例,缺省为8

-XX:G1ReservePercent=n——保留的堆大小,减少晋升过程中出错的可能性,也就是增加可用的to-space内存,缺省是10

-XX:G1HeapRegionSize=n——G1中,堆分为大小相等的区域。这个参数设置区域的大小,缺省值取决于堆的总大小,有效取值是1M-32M。

最佳实践

使用G1时的最佳实践

1、不要设置年轻代的大小(-Xmn),否则会扰乱G1的缺省行为,JVM也不会满足用户指定的暂停时间。而且设置了固定值的话,G1将无法随需扩展年轻代的大小

2、GC暂停时间不是100%能保证的

3、如果GC的晋升过程中遇到堆区域溢出(使用-XX:+PrintGCDetails看到to-space overflow),可以通过下面几种方式避免:

  • 增加-XX:G1ReservePercent=n,缺省值是10。这可以增加可用的to-space内存
  • 使用-XX:ConcGCThreads=n增加标记线程数目
  • 大小: 19.4 KB
2
0
分享到:
评论
1 楼 bo_hai 2015-10-09  
总结的真好!

相关推荐

    HotSpot实战高清版本

    Cache、Perf Data、Crash 分析方法、转储分析方法、 垃圾收集器的设计演进、CMS 和 G1 收集器、栈、JVM 对硬件寄存器的利用、栈顶缓存技术、解释器、字节 码表、转发表、Stubs、Code Cache、Code 生成器、JIT 编译器...

    JAVA虚拟机精讲 pdf

    本书以极其精练的语句诠释了HotSpot VM 的方方面面,比如:字节码的编译原理、字节码的内部组成结构、通过源码的方式剖析HotSpot VM 的启动过程和初始化过程、Java 虚拟机的运行时内存、垃圾收集算法、垃圾收集器...

    HotSpot实战

    包括OpenJDK与HotSpot项目、编译和调试HotSpot的方法、HotSpot内核结构、Launcher、OOP-Klass对象表示系统、链接、运行时数据区、方法区、常量池和常量池Cache、Perf Data、Crash分析方法、转储分析方法、垃圾收集器...

    降低Java垃圾回收开销的5条建议

    从 serial 垃圾回收器到CMS 收集器, JVM 见证了许多 GC 实现,而 G1 将成为其下一代垃圾回收器。  随着垃圾收集器的发展,每一代 GC 与其上一代相比,都带来了巨大的进步和改善。parallel GC 与 serial GC 相比,...

    JAVA虚拟机精讲

    比如:字节码的编译原理、字节码的内部组成结构、通过源码的方式剖析HotSpot VM 的启动过程和初始化过程、Java 虚拟机的运行时内存、垃圾收集算法、垃圾收集器(重点讲解了Serial 收集器、ParNew 收集器、Parallel ...

    Java虚拟机精讲.高翔龙.带书签完整版.pdf

    本书以极其精练的语句诠释了HotSpot VM 的方方面面,比如:字节码的编译原理、字节码的内部组成结构、通过源码的方式剖析HotSpot VM 的启动过程和初始化过程、Java 虚拟机的运行时内存、垃圾收集算法、垃圾收集器...

    java虚拟机精讲(电子工业出版社出版)

    本书以极其精练的语句诠释了 HotSpot VM的方方面面,比如:字节码的编译原理、字节码的内部组成结构、通过源码的方式剖析 HotSpot VM 的启动过程和初始化过程、Java 虚拟机的运行时内存、垃圾收集算法、垃圾收集器...

    深入理解_Java_虚拟机 JVM_高级特性与最佳实践

    / 57 3.4.3 Parallel Scavenge收集器 / 59 3.4.4 Serial Old收集器 / 60 3.4.5 Parallel Old收集器 / 61 3.4.6 CMS收集器 / 61 3.4.7 G1收集器 / 64 3.4.8 垃圾收集器参数总结 / 64 3.5 内存分配与回收策略 /...

    Java虚拟机

    3.5.7 G1收集器 3.5.8 理解GC日志 3.5.9 垃圾收集器参数总结 3.6 内存分配与回收策略 3.6.1 对象优先在Eden分配 3.6.2 大对象直接进入老年代 3.6.3 长期存活的对象将进入老年代 3.6.4 动态对象年龄判定 ...

Global site tag (gtag.js) - Google Analytics