G1垃圾收集器入门

G1垃圾收集器概述

一步步介绍G1

G1收集器采用一种不同的方式来分配堆. 下面通过图解的方式一步步地讲述G1系统.

1. G1的堆内存结构

堆内存被划分为固定大小的多个区域.

每个heap区(Region)的大小在JVM启动时就确定了. JVM 通常生成 2000 个左右的heap区, 根据堆内存的总大小,区的size范围允许为 1Mb 到 32Mb.

2. G1 堆空间分配

实际上,这些区域(regions)被映射为逻辑上的 Eden, Survivor, 和 old generation(老年代)空间.

图中的颜色标识了每一个区域属于哪个角色. 存活的对象从一块区域转移(复制或移动)到另一块区域。设计成 heap 区的目的是为了并行地进行垃圾回收(的同时停止/或不停止其他应用程序线程).

如图所示,heap区可以分配为 Eden, Survivor, 或 old generation(老年代)区. 此外,还有第四种类型的对象被称为巨无霸区域(Humongous regions),这种巨无霸区是设计了用来保存比标准heap区大50%及以上的对象, 它们存储在一组连续的区中. 最后一个类型是堆内存中的未使用区(unused areas).

备注: 截止英文原文发表时,巨无霸对象的回收还没有得到优化. 因此,您应该尽量避免创建太大(大于32MB?)的对象.

3. G1中的年轻代(Young Generation)

堆被分为大约2000个区. 最小size为1 Mb, 最大size为 32Mb. 蓝色的区保存老年代对象,绿色区域保存年轻代对象.

注意G1中各代的heap区不像老一代垃圾收集器一样要求各部分是连续的.

4. G1中的一次年轻代GC

存活的对象被转移(copied or moved)到一个/或多个存活区(survivor regions). 如果存活时间达到阀值,这部分对象就会被提升到老年代(promoted to old generation regions).

此时会有一次 stop the world(STW)暂停. 会计算出 Eden大小和 survivor 大小,给下一次年轻代GC使用. 清单统计信息(Accounting)保存了用来辅助计算size. 诸如暂停时间目标之类的东西也会纳入考虑.

这种方法使得调整各代区域的尺寸很容易, 让其更大或更小一些以满足需要.

5. G1的一次年轻代GC完成后

存活对象被转移到存活区(survivor regions) 或 老年代(old generation regions).

刚刚被提升上来的对象用深绿色显示. Survivor 区用绿色表示.

总结起来,G1的年轻代收集归纳如下:

  • 堆一整块内存空间,被分为多个heap区(regions).
  • 年轻代内存由一组不连续的heap区组成. 这使得在需要时很容易进行容量调整.
  • 年轻代的垃圾收集,或者叫 young GCs, 会有 stop the world 事件. 在操作时所有的应用程序线程都会被暂停(stopped).
  • 年轻代 GC 通过多线程并行进行.
  • 存活的对象被拷贝到新的 survivor 区或者老年代.

Old Generation Collection with G1

和 CMS 收集器相似, G1 收集器也被设计为用来对老年代的对象进行低延迟(low pause)的垃圾收集. 下表描述了G1收集器在老年代进行垃圾回收的各个阶段.

G1 收集阶段 - 并发标记周期阶段(Concurrent Marking Cycle Phases)

G1 收集器在老年代堆内存中执行下面的这些阶段. 注意有些阶段也是年轻代垃圾收集的一部分.

(1) 初始标记(Initial Mark):(Stop the World Event,所有应用线程暂停) 此时会有一次 stop the world(STW)暂停事件. 在G1中, 这附加在(piggybacked on)一次正常的年轻代GC. 标记可能有引用指向老年代对象的survivor区(根regions).

(2) 扫描根区域(Root Region Scanning) 扫描 survivor 区中引用到老年代的引用. 这个阶段应用程序的线程会继续运行. 在年轻代GC可能发生之前此阶段必须完成.

(3) 并发标记(Concurrent Marking) 在整个堆中查找活着的对象. 此阶段应用程序的线程正在运行. 此阶段可以被年轻代GC打断(interrupted).

(4) 再次标记(Remark) (Stop the World Event,所有应用线程暂停) 完成堆内存中存活对象的标记. 使用一个叫做 snapshot-at-the-beginning(SATB, 起始快照)的算法, 该算法比CMS所使用的算法要快速的多.

(5) 清理(Cleanup) (Stop the World Event,所有应用线程暂停,并发执行)

在存活对象和完全空闲的区域上执行统计(accounting). (Stop the world)

擦写 Remembered Sets. (Stop the world)

重置空heap区并将他们返还给空闲列表(free list). (Concurrent, 并发)

(*) 拷贝(Copying) (Stop the World Event,所有应用线程暂停) 产生STW事件来转移或拷贝存活的对象到新的未使用的heap区(new unused regions). 只在年轻代发生时日志会记录为 `[GC pause (young)]`. 如果在年轻代和老年代一起执行则会被日志记录为 `[GC Pause (mixed)]`.

G1老年代收集步骤

顺着定义的阶段,让我们看看G1收集器如何处理老年代(old generation).

6. 初始标记阶段(Initial Marking Phase)

存活对象的初始标记被固定在年轻代垃圾收集里面. 在日志中被记为 GC pause (young)(inital-mark)

7. 并发标记阶段(Concurrent Marking Phase)

如果找到空的区域(如用红叉“X”标示的区域), 则会在 Remark 阶段立即移除. 当然,"清单(accounting)"信息决定了活跃度(liveness)的计算.

8. 再次标记阶段(Remark Phase)

空的区域被移除并回收。现在计算所有区域的活跃度(Region liveness).

9. 拷贝/清理阶段(Copying/Cleanup)

G1选择“活跃度(liveness)”最低的区域, 这些区域可以最快的完成回收. 然后这些区域和年轻代GC在同时被垃圾收集 . 在日志被标识为 [GC pause (mixed)]. 所以年轻代和老年代都在同一时间被垃圾收集.

10.拷贝/清理之后(After Copying/Cleanup)

所选择的区域被收集和压缩到下图所示的深蓝色区域和深绿色区域.

老年代GC(Old Generation GC)总结

总结下来,G1对老年代的GC有如下几个关键点:

  • 并发标记清理阶段(Concurrent Marking Phase)
    • 活跃度信息在程序运行的时候被并行计算出来
    • 活跃度(liveness)信息标识出哪些区域在转移暂停期间最适合回收.
    • 不像CMS一样有清理阶段(sweeping phase).
  • 再次标记阶段(Remark Phase)
    • 使用的 Snapshot-at-the-Beginning (SATB, 开始快照) 算法比起 CMS所用的算法要快得多.
    • 完全空的区域直接被回收.
  • 拷贝/清理阶段(Copying/Cleanup Phase)
    • 年轻代与老年代同时进行回收.
    • 老年代的选择基于其活跃度(liveness).

命令行参数与最佳实践

命令行基本参数

要启用 G1 收集器请使用: -XX:+UseG1GC

下面是启动 Java2Demo示例程序的命令行示例. Java2Demo位于下载 JDK demos and samples 后解压的文件夹中:

java -Xmx50m -Xms50m -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -jar c:\javademos\demo\jfc\Java2D\Java2demo.jar

关键命令行开关

-XX:+UseG1GC - 让 JVM 使用 G1 垃圾收集器.

-XX:MaxGCPauseMillis=200 - 设置最大GC停顿时间(GC pause time)指标(target). 这是一个软性指标(soft goal), JVM 会尽力去达成这个目标. 所以有时候这个目标并不能达成. 默认值为 200 毫秒.

-XX:InitiatingHeapOccupancyPercent=45 - 启动并发GC时的堆内存占用百分比. G1用它来触发并发GC周期,基于整个堆的使用率,而不只是某一代内存的使用比例。值为 0 则表示“一直执行GC循环)‘. 默认值为 45 (例如, 全部的 45% 或者使用了45%).

最佳实践

在使用 G1 作为垃圾收集器时,你应该遵循下面这些最佳实践的指导.

不要设置年轻代的大小(Young Generation Size)

假若通过 -Xmn 显式地指定了年轻代的大小, 则会干扰到 G1收集器的默认行为.

  • G1在垃圾收集时将不再关心暂停时间指标. 所以从本质上说,设置年轻代的大小将禁用暂停时间目标.
  • G1在必要时也不能够增加或者缩小年轻代的空间. 因为大小是固定的,所以对更改大小无能为力.
响应时间指标(Response Time Metrics)

设置 XX:MaxGCPauseMillis=<N> 时不应该使用平均响应时间(ART, average response time) 作为指标,而应该考虑使用目标时间的90%或者更大作为响应时间指标. 也就是说90%的用户(客户端/?)请求响应时间不会超过预设的目标值. 记住,暂停时间只是一个目标,并不能保证总是得到满足.

什么是转移失败(Evacuation Failure)?

对 survivors 或 promoted objects 进行GC时如果JVM的heap区不足就会发生提升失败(promotion failure). 堆内存不能继续扩充,因为已经达到最大值了. 当使用 -XX:+PrintGCDetails 时将会在GC日志中显示 to-space overflow (to-空间溢出)。

这是很昂贵的操作!

  • GC仍继续所以空间必须被释放.
  • 拷贝失败的对象必须被放到正确的位置(tenured in place).
  • CSet指向区域中的任何 RSets 更新都必须重新生成(regenerated).
  • 所有这些步骤都是代价高昂的.
如何避免转移失败(Evacuation Failure)

要避免避免转移失败, 考虑采纳下列选项.

  • 增加堆内存大小
    • 增加 -XX:G1ReservePercent=n, 其默认值是 10.
    • G1创建了一个假天花板(false ceiling),在需要更大 ‘to-space‘ 的情况下会尝试从保留内存获取(leave the reserve memory free).
  • 更早启动标记周期(marking cycle)
  • 通过采用 -XX:ConcGCThreads=n 选项增加标记线程(marking threads)的数量.
G1 的 GC 参数完全列表

下面是完整的 G1 的 GC 开关参数列表. 在使用时请记住上面所述的最佳实践.

选项/默认值  说明

-XX:+UseG1GC

使用 G1 (Garbage First) 垃圾收集器

-XX:MaxGCPauseMillis=n

设置最大GC停顿时间(GC pause time)指标(target). 这是一个软性指标(soft goal), JVM 会尽量去达成这个目标.

-XX:InitiatingHeapOccupancyPercent=n

启动并发GC周期时的堆内存占用百分比. G1之类的垃圾收集器用它来触发并发GC周期,基于整个堆的使用率,而不只是某一代内存的使用比. 值为 0 则表示"一直执行GC循环". 默认值为 45.

-XX:NewRatio=n

新生代与老生代(new/old generation)的大小比例(Ratio). 默认值为 2.

-XX:SurvivorRatio=n eden/survivor

空间大小的比例(Ratio). 默认值为 8.

-XX:MaxTenuringThreshold=n

提升年老代的最大临界值(tenuring threshold). 默认值为 15.

-XX:ParallelGCThreads=n

设置垃圾收集器在并行阶段使用的线程数,默认值随JVM运行的平台不同而不同.

-XX:ConcGCThreads=n

并发垃圾收集器使用的线程数量. 默认值随JVM运行的平台不同而不同.

-XX:G1ReservePercent=n

设置堆内存保留为假天花板的总量,以降低提升失败的可能性. 默认值是 10.

-XX:G1HeapRegionSize=n

使用G1时Java堆会被分为大小统一的的区(region)。此参数可以指定每个heap区的大小. 默认值将根据 heap size 算出最优解. 最小值为 1Mb, 最大值为 32Mb.

记录G1的GC日志

我们要介绍的最后一个主题是使用日志信息来分享G1收集器的性能. 本节简要介绍垃圾收集的相关参数,以及日志中打印的相关信息.

设置日志细节(Log Detail)

可以设置3种不同的日志级别.

(1) -verbosegc (等价于 -XX:+PrintGC) 设置日志级别为  fine.

日志输出示例

[GC pause (G1 Humongous Allocation) (young) (initial-mark) 24M- >21M(64M), 0.2349730 secs]
[GC pause (G1 Evacuation Pause) (mixed) 66M->21M(236M), 0.1625268 secs]

(2) -XX:+PrintGCDetails 设置日志级别为 更好 finer. 使用此选项会显示以下信息:

  • 每个阶段的 Average, Min, 以及 Max 时间.
  • 根扫描(Root Scan), RSet 更新(同时处理缓冲区信息), RSet扫描(Scan), 对象拷贝(Object Copy), 终止(Termination, 包括尝试次数).
  • 还显示 “other” 执行时间, 比如选择 CSet, 引用处理(reference processing), 引用排队(reference enqueuing) 以及释放(freeing) CSet等.
  • 显示 Eden, Survivors 以及总的 Heap 占用信息(occupancies).

日志输出示例

[Ext Root Scanning (ms): Avg: 1.7 Min: 0.0 Max: 3.7 Diff: 3.7]
[Eden: 818M(818M)->0B(714M) Survivors: 0B->104M Heap: 836M(4096M)->409M(4096M)]

(3) -XX:+UnlockExperimentalVMOptions -XX:G1LogLevel=finest 设置日志级别为 最好 finest. 和 finer 级别类似, 包含每个 worker 线程信息.

[Ext Root Scanning (ms): 2.1 2.4 2.0 0.0
           Avg: 1.6 Min: 0.0 Max: 2.4 Diff: 2.3]
       [Update RS (ms):  0.4  0.2  0.4  0.0
           Avg: 0.2 Min: 0.0 Max: 0.4 Diff: 0.4]
           [Processed Buffers : 5 1 10 0
           Sum: 16, Avg: 4, Min: 0, Max: 10, Diff: 10]

Determining Time

有两个参数决定了GC日志中打印的时间显示形式.

(1) -XX:+PrintGCTimeStamps - 显示从JVM启动时算起的运行时间.

日志输出示例

1.729: [GC pause (young) 46M->35M(1332M), 0.0310029 secs]

(2) -XX:+PrintGCDateStamps - 在每条记录前加上日期时间.

日志输出示例

2012-05-02T11:16:32.057+0200: [GC pause (young) 46M->35M(1332M), 0.0317225 secs]

理解 G1 日志

为了使你更好地理解GC日志, 本节通过实际的日志输出,定义了许多专业术语. 下面的例子显示了GC日志的内容,并加上日志中出现的术语和值的解释说明.

Note: 更多信息请参考 Poonam Bajaj的博客: G1垃圾回收日志.

G1 日志相关术语

  • Clear CT
  • CSet
  • External Root Scanning
  • Free CSet
  • GC Worker End
  • GC Worker Other
  • Object Copy
  • Other
  • Parallel Time
  • Ref Eng
  • Ref Proc
  • Scanning Remembered Sets
  • Termination Time
  • Update Remembered Set
  • Worker Start
Parallel Time(并行阶段耗时)
414.557: [GC pause (young), 0.03039600 secs] [Parallel Time: 22.9 ms]
[GC Worker Start (ms): 7096.0 7096.0 7096.1 7096.1 706.1 7096.1 7096.1 7096.1 7096.2 7096.2 7096.2 7096.2
       Avg: 7096.1, Min: 7096.0, Max: 7096.2, Diff: 0.2]

Parallel Time – 主要并行部分运行停顿的整体时间

Worker Start – 各个工作线程(workers)启动时的时间戳(Timestamp)

Note: 日志是根据 thread id 排序,并且每条记录都是一致的.

External Root Scanning(外部根扫描)
[Ext Root Scanning (ms): 3.1 3.4 3.4 3.0 4.2 2.0 3.6 3.2 3.4 7.7 3.7 4.4
     Avg: 3.8, Min: 2.0, Max: 7.7, Diff: 5.7]

External root scanning - 扫描外部根花费的时间(如指向堆内存的系统词典(system dictionary)等部分)

Update Remembered Set(更新 RSet)
[Update RS (ms): 0.1 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 Avg: 0.0, Min: 0.0, Max: 0.1, Diff: 0.1]
   [Processed Buffers : 26 0 0 0 0 0 0 0 0 0 0 0
    Sum: 26, Avg: 2, Min: 0, Max: 26, Diff: 26]

Update Remembered Set - 必须更新在pause之前已经完成但尚未处理的缓冲. 花费的时间取决于cards的密度。cards越多,耗费的时间就越长。

Scanning Remembered Sets(扫描 RSets)
[Scan RS (ms): 0.4 0.2 0.1 0.3 0.0 0.0 0.1 0.2 0.0 0.1 0.0 0.0 Avg: 0.1, Min: 0.0, Max: 0.4, Diff: 0.3]F

Scanning Remembered Sets - 查找指向 Collection Set 的指针(pointers)

Object Copy(对象拷贝)
[Object Copy (ms): 16.7 16.7 16.7 16.9 16.0 18.1 16.5 16.8 16.7 12.3 16.4 15.7 Avg: 16.3, Min: 12.3, Max:  18.1, Diff: 5.8]

Object copy – 每个独立的线程在拷贝和转移对象时所消耗的时间.

Termination Time(结束时间)
[Termination (ms): 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 Avg: 0.0, Min: 0.0, Max: 0.0, Diff: 0.0] [Termination Attempts : 1 1 1 1 1 1 1 1 1 1 1 1 Sum: 12, Avg: 1, Min: 1, Max: 1, Diff: 0]

Termination time - 当worker线程完成了自己那部分对象的复制和扫描,就进入终止协议(termination protocol)。它查找未完成的工作(looks for work to steal), 一旦它完成就会再进入终止协议。 终止尝试记录(Termination attempt counts)所有查找工作的尝试次数(attempts to steal work).

GC Worker End
[GC Worker End (ms): 7116.4 7116.3 7116.4 7116.3 7116.4 7116.3 7116.4 7116.4 7116.4 7116.4 7116.3 7116.3
    Avg: 7116.4, Min: 7116.3, Max: 7116.4, Diff:   0.1]
[GC Worker (ms): 20.4 20.3 20.3 20.2 20.3 20.2 20.2 20.2 20.3 20.2 20.1 20.1
     Avg: 20.2, Min: 20.1, Max: 20.4, Diff: 0.3]

GC worker end time – 独立的 GC worker 停止时的时间戳.

GC worker time – 每个独立的 GC worker 线程消耗的时间.

GC Worker Other
[GC Worker Other (ms): 2.6 2.6 2.7 2.7 2.7 2.7 2.7 2.8 2.8 2.8 2.8 2.8
    Avg: 2.7, Min: 2.6, Max: 2.8, Diff: 0.2]

GC worker other – 每个GC线程中不能归属到之前列出的worker阶段的其他时间. 这个值应该很低. 过去我们见过很高的值,是由于JVM的其他部分的瓶颈引起的(例如在分层[Tiered]代码缓存[Code Cache]占有率的增加)。

Clear CT
[Clear CT: 0.6 ms]

清除 RSet 扫描元数据(scanning meta-data)的 card table 消耗的时间.

Other
[Other: 6.8 ms]

其他各种GC暂停的连续阶段花费的时间.

CSet
[Choose CSet: 0.1 ms]

敲定要进行垃圾回收的region集合时消耗的时间. 通常很小,在必须选择 old 区时会稍微长一点点.

Ref Proc
[Ref Proc: 4.4 ms]

处理 soft, weak, 等引用所花费的时间,不同于前面的GC阶段

Ref Enq
[Ref Enq: 0.1 ms]

将 soft, weak, 等引用放置到待处理列表(pending list)花费的时间.

Free CSet
[Free CSet: 2.0 ms]

释放刚被垃圾收集的 heap区所消耗的时间,包括对应的remembered sets。

总结

在此OBE中, 您对Java JVM 中的G1垃圾收集器有了个大致的了解。首先你学到了为何堆和垃圾收集器是所有Java JVM的关键部分。接下来讲述了使用CMS和G1收集器进行垃圾回收的工作方式. 接下来,您了解了G1的命令行参数/开关以及和使用它们的最佳实践。最后,您了解了日志对象以及GC日志中的数据。

在本教程中,你学到了这些知识:

  • Java JVM 的组成部分
  • 对 G1 的概述
  • 概述 CMS 垃圾收集器
  • 概述 G1 垃圾收集器
  • 命令行参数与最佳实践
  • G1 的日志信息
时间: 2024-08-06 07:56:54

G1垃圾收集器入门的相关文章

转 G1垃圾收集器入门

转自:http://blog.csdn.net/zhanggang807/article/details/45956325 最近在复习Java GC,因为G1比较新,JDK1.7才正式引入,比较艰难的找到一篇写的很棒的文章,粘过来mark下.总结这篇文章和其他的资料,G1可以基本稳定在0.5s到1s左右的延迟,但是并不能保证更低的比如毫秒级(金融场景,所以说涉及到钱的,对技术要求真高),号称zing可以(但是一般做到低延时,在其他方面肯定有所损耗,比如吞吐),但是没有实际去研究过这种.另外,G1

G1 垃圾收集器入门

G1 垃圾收集器入门 概览 目的 这个教程覆盖了如何使用G1垃圾收集器和它是怎样被Hotspot JVM使用的,你会学到G1收集器内部是如何工作的,使用G1时的一些关键命令行开关和记录它的操作的一些选项. 完成耗时 大约1小时 介绍 这个OBE(Oracle By Example)覆盖了Java里的Java虚拟机G1垃圾回收的基本概念,在OBE的第一部分, 在介绍垃圾收集器和性能时会附带提供JVM的概览.下一部分回顾一下Hotspot JVM的CMS收集器如何工作.然后,一步一步来指导使用Hot

G1 垃圾收集器

概念先知 什么是垃圾回收 简单的说垃圾回收就是回收内存中不再使用的对象. 垃圾回收的基本步骤: 查找内存中不再使用的对象 释放这些对象占用的内存 查找内存中不再使用的对象 如何判断哪些对象不再被使用呢?有2个方法: 引用计数法 引用计数法就是如果一个对象没有被任何引用指向,则可视之为垃圾.这种方法的缺点就是不能检测到环的存在. 根搜索算法 根搜索算法的基本思路就是通过一系列名为"GC Roots"的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference

JVM中的G1垃圾收集器

G1 垃圾收集器是Jdk7的新特性之一.Jdk7+版本都可以自主配置G1作为JVM GC选项: 作为JVM GC算法的一次重大升级.JDK7u后G1已相对稳定.且未来计划替代CMS.所以有必要深入了解下:不同于其他的分代回收算法.G1将堆空间划分成了互相独立的区块.每块区域既有可能属于O区.也有可能是Y区,且每类区域空间可以是不连续的(对比CMS的O区和Y区都必须是连续的).这种将O区划分成多块的理念源于:当并发后台线程寻找可回收的对象时.有些区块包含可回收的对象要比其他区块多很多.虽然在清理这

G1垃圾收集器和CMS垃圾收集器 (http://mm.fancymore.com/reading/G1-CMS%E5%9E%83%E5%9C%BE%E7%AE%97%E6%B3%95.html#toc_8)

参考来源 JVM 体系架构 堆/栈的内存分配 静态和非静态方法的内存分配 CMS 回收算法 应用场景 CMS 垃圾收集阶段划分(Collection Phases) CMS什么时候启动 CMS缺点 G1收集算法 G1的发展 分代垃圾回收瓶颈 G1使用场景 G1特点 G1堆内存的分配 G1的进程内存占用(Footprint) G1 收集器收集过程 G1命令行参数 记录G1的GC日志 G1性能调优 参考来源 http://blog.csdn.net/renfufei/article/details/

深入理解 Java G1 垃圾收集器--转

原文地址:http://blog.jobbole.com/109170/?utm_source=hao.jobbole.com&utm_medium=relatedArticle 本文首先简单介绍了垃圾收集的常见方式,然后再分析了G1收集器的收集原理,相比其他垃圾收集器的优势,最后给出了一些调优实践. 一,什么是垃圾回收 首先,在了解G1之前,我们需要清楚的知道,垃圾回收是什么?简单的说垃圾回收就是回收内存中不再使用的对象. 垃圾回收的基本步骤 回收的步骤有2步: 查找内存中不再使用的对象 释放

理解G1垃圾收集器日志

理解G1垃圾收集器日志 发表这个文章的目的是为了解释使用了G1垃圾收集器的一些跟踪和诊断选项而生成出来的垃圾收集日志的意义.我们来看一下使用一个提供最详细的信息级别的生产环境选项PrintGCDetails生成的输出日志.同时,我们也会看一下启用的两个诊断选项 -XX:+UnlockDiagnosticVMOptions . -XX:G1PrintRegionLivenessInfo 的输出信息,它们会打印出在标记周期末尾每个区域的活跃对象使用了总空间.占用大小和 -XX:+G1PrintHea

GC垃圾回收 | 深入理解G1垃圾收集器和GC日志

来源:并发编程网链接:http://ifeve.com/深入理解G1垃圾收集器/ G1 GC是Jdk7的新特性之一.Jdk7+版本都可以自主配置G1作为JVM GC选项:作为JVM GC算法的一次重大升级.DK7u后G1已相对稳定.且未来计划替代CMS.所以有必要深入了解下: 不同于其他的分代回收算法.G1将堆空间划分成了互相独立的区块.每块区域既有可能属于O区.也有可能是Y区,且每类区域空间可以是不连续的(对比CMS的O区和Y区都必须是连续的).这种将O区划分成多块的理念源于:当并发后台线程寻

详解 JVM Garbage First(G1) 垃圾收集器

前言    Garbage First(G1)是垃圾收集领域的最新成果,同时也是HotSpot在JVM上力推的垃圾收集器,并赋予取代CMS的使命.如果使用Java 8/9,那么有很大可能希望对G1收集器进行评估.本文详细首先对JVM其他的垃圾收集器进行总结,并与G1进行了简单的对比:然后通过G1的内存模型.G1的活动周期,对G1的工作机制进行了介绍:同时还在介绍过程中,描述了可能需要引起注意的优化点.笔者希望通过本文,让有一定JVM基础的读者能尽快掌握G1的知识点. 第一章 概述 G1(Garb