ChatGPT解决这个技术问题 Extra ChatGPT

G1 上的 Java 7 (JDK 7) 垃圾收集和文档

Java 7 已经发布了一段时间,但我找不到任何关于垃圾收集器配置的好资源,特别是新的 G1 收集器。

我的问题:

G1 是 Java 7 中的默认收集器吗?如果不是,我该如何激活 G1? Java7中g1有哪些可选设置? Java 7 中的 cms 或并行收集器等其他收集器是否有任何更改?我在哪里可以找到关于 Java 7 中垃圾收集的优秀文档?


C
Carey

G1 垃圾收集器不是我安装的 Java 版本 1.7.0_01 的默认设置。您可以通过使用一些额外的命令行选项来亲自查看:

> java -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -version
-XX:InitialHeapSize=132304640 -XX:MaxHeapSize=2116874240 -XX:ParallelGCThreads=4 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
java version "1.7.0_01"
Java(TM) SE Runtime Environment (build 1.7.0_01-b08)
Java HotSpot(TM) 64-Bit Server VM (build 21.1-b02, mixed mode)
Heap
 PSYoungGen      total 37696K, used 1293K [0x00000007d5eb0000, 0x00000007d88c0000, 0x0000000800000000)
  eden space 32320K, 4% used [0x00000007d5eb0000,0x00000007d5ff3408,0x00000007d7e40000)
  from space 5376K, 0% used [0x00000007d8380000,0x00000007d8380000,0x00000007d88c0000)
  to   space 5376K, 0% used [0x00000007d7e40000,0x00000007d7e40000,0x00000007d8380000)
 PSOldGen        total 86144K, used 0K [0x0000000781c00000, 0x0000000787020000, 0x00000007d5eb0000)
  object space 86144K, 0% used [0x0000000781c00000,0x0000000781c00000,0x0000000787020000)
 PSPermGen       total 21248K, used 2032K [0x000000077ca00000, 0x000000077dec0000, 0x0000000781c00000)
  object space 21248K, 9% used [0x000000077ca00000,0x000000077cbfc288,0x000000077dec0000)

不过,您不再需要启用实验选项来打开 G1 收集器:

> java -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseG1GC -version
-XX:InitialHeapSize=132304640 -XX:MaxHeapSize=2116874240 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedOops -XX:+UseG1GC -XX:-UseLargePagesIndividualAllocation
java version "1.7.0_01"
Java(TM) SE Runtime Environment (build 1.7.0_01-b08)
Java HotSpot(TM) 64-Bit Server VM (build 21.1-b02, mixed mode)
Heap
 garbage-first heap   total 130048K, used 0K [0x000000077ca00000, 0x0000000784900000, 0x00000007fae00000)
  region size 1024K, 1 young (1024K), 0 survivors (0K)
 compacting perm gen  total 20480K, used 2032K [0x00000007fae00000, 0x00000007fc200000, 0x0000000800000000)
   the space 20480K,   9% used [0x00000007fae00000, 0x00000007faffc288, 0x00000007faffc400, 0x00000007fc200000)
No shared spaces configured.

我不知道你在哪里可以找到任何好的文档。


这对于 OSX 上的 1.7.0_09 仍然有效
直接从 Oracle 网站获取的 linux/amd64 上的 Oracle JDK 7u17 并非如此。它显示 -XX:+UseParallelGC
F
Florakel

Oracle 终于在 Java 7 U4 中正式发布了 G1:http://www.oracle.com/technetwork/java/javase/7u4-relnotes-1575007.html

说明:http://docs.oracle.com/javase/7/docs/technotes/guides/vm/G1.html

命令行选项:http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html#G1Options

不过,我不认为它是 Java 7 中的默认收集器。对于服务器,默认是 Java 6 中的并行收集器。


服务器由 2 个内核和 2 GB ram 或更多定义。可以通过 hg.openjdk.java.net/jdk7u/jdk7u/hotspot/file/0d82bf449a61/src 找到详细信息 - 查看文件 ./share/tools/launcher/java.c 和 ./share/vm/runtime/os.cpp
C
Community

是的,G1 是 Java 1.7 JVM 中新的标准垃圾收集器。

Here 您可以找到大量有关如何使用和配置新垃圾收集器的信息:

使用 G1 G1 仍被认为是实验性的,可以通过以下两个参数启用: -XX:+UnlockExperimentalVMOptions -XX:+UseG1GC 要设置 GC 暂停时间目标,请使用以下参数: -XX:MaxGCPauseMillis =50(用于暂停time target of 50ms) 使用 G1,可以指定 GC 暂停的时间间隔不应超过上面给出的时间: -XX:GCPauseIntervalMillis =200 (对于 200ms 的暂停间隔目标) 注意上面的两个选项代表目标,而不是承诺或保证。它们可能在某些情况下工作得很好,但在其他情况下却不行,而且 GC 可能并不总是能够服从它们。或者,可以明确指定年轻代的大小以影响疏散暂停时间: -XX:+G1YoungGenSize=512m(对于 512 兆字节的年轻代) G1 也使用等价的幸存者空间,自然是一组(可能是不连续的)区域。它们的大小可以用通常的参数来指定(例如,-XX:SurvivorRatio=6)。最后,要充分发挥 G1 的潜力,请尝试设置当前默认禁用的这两个参数,因为它们可能会发现罕见的竞争条件: -XX:+G1ParallelRSetUpdatingEnabled -XX:+G1ParallelRSetScanningEnabled 还有一点需要注意的是 G1 非常当设置了 -XX:+PrintGCDetails 时,与其他 HotSpot GC 相比更详细。这是因为它打印每个 GC 线程的时间和其他对分析和故障排除非常有帮助的信息。如果你想要更简洁的 GC 日志,请切换到使用 -verbosegc(虽然建议获取更详细的 GC 日志)。

我还发现 this 文章对理解 G1 的内部非常有帮助。

更多信息here


我看过这些资源。但是第一篇文章是关于 JDK 6 中的 G1,当时它还是一个实验选项。其他文章是关于 JDK 7 和至少 1 年的 beta 版本。我正在寻找来自 Oracle 或 JDK 团队的更多最新信息或官方文档。
L
Luke Usherwood

1. G1 是 Java 7 中的默认收集器吗(...)

this Java 5 page 的规则仍然适用于 Java 7(和 AFAIK、Java 8):

在运行服务器 VM 的服务器级机器上,垃圾收集器 (GC) 已从以前的串行收集器 (-XX:+UseSerialGC) 更改为并行收集器 (-XX:+UseParallelGC)。

但也要考虑:

64 位 JVM 不附带 -client VM,因此始终是“服务器类”

从 Java 7 开始,使用 -XX:+UseParallelGC (无论是设置还是隐含)还意味着 -XX:+UseParallelOldGC (即除非明确禁用)

例如,如果在 Windows x64 上运行...

Java 7 64 位,默认情况下您将获得并行 GC(适用于年轻代和年老代)。

Java 8 32 位,默认情况下您将获得串行 GC(两代)

1. (...) 如何激活 G1?

从 Java 7 开始,只需 -XX:+UseG1GCwhen 您可能还想:

如果应用程序具有以下一个或多个特征,则今天使用 CMS 或 ParallelOld 垃圾收集器运行的应用程序将受益于切换到 G1。超过 50% 的 Java 堆被实时数据占用。对象分配率或提升率差异很大。不需要的长时间垃圾收集或压缩暂停(超过 0.5 到 1 秒)

2、g1在Java7中有哪些可选设置?

我自己没有使用过 G1,但 I gather 它遵循用于调整其他并行收集器的相同基本“吞吐量/人体工程学”标志。根据我使用 Parallel GC 的经验,-XX:GCTimeRatio 一直是提供预期速度-内存权衡的关键。 YMMV。

列出了 G1 特定的选项here

3. Java 7 中的 (...) cms 或并行收集器是否发生了变化?

不知道,but...

G1 计划作为 Concurrent Mark-Sweep Collector (CMS) 的长期替代品

4. 在哪里可以找到关于 Java 7 垃圾收集的优秀文档?

找到它可能会很痛苦,不是吗?我发现的最好的“中心”页面可能是这个:

http://www.oracle.com/technetwork/java/javase/tech/index-jsp-140228.html

需要一些深入的阅读,但如果你需要做一些调整,值得花时间。特别有见地的是:Garbage Collector Ergonomics


R
Ravindra babu

G1 是 Java 7 中的默认收集器吗?如果不是,我该如何激活 G1?

G1 不是 Java 7 中的默认收集器。-XX:+UseG1GC 将启用 G1GC

Java7中g1有哪些可选设置?

有许多。查看这篇 oracle 文章以获取完整信息。

G1 GC 是一种自适应垃圾收集器,其默认设置使其无需修改即可高效工作。

由于这个原因,自定义关键参数

-XX:MaxGCPauseMillis
-XX:G1HeapRegionSize
-XX:ParallelGCThreads
-XX:ConcGCThreads

并将所有其他参数保留为默认值。

这是重要选项及其默认值的列表。此列表适用于最新的 Java HotSpot VM,版本 24。您可以在 JVM 命令行上调整和调整 G1 GC 设置。

重要默认值:

-XX:G1HeapRegionSize=n

设置 G1 区域的大小。该值将是 2 的幂,范围可以从 1MB 到 32MB。目标是基于最小 Java 堆大小拥有大约 2048 个区域。

-XX:MaxGCPauseMillis=200

为所需的最大暂停时间设置目标值。默认值为 200 毫秒。指定的值不适应您的堆大小。

-XX:G1NewSizePercent=5

设置堆的百分比以用作年轻代大小的最小值。默认值为 Java 堆的 5%。

-XX:G1MaxNewSizePercent=60

设置堆大小的百分比以用作年轻代大小的最大值。默认值为 Java 堆的 60%。

-XX:ParallelGCThreads=n

设置 STW 工作线程的值。将 n 的值设置为逻辑处理器的数量。 n 的值与最大为 8 的逻辑处理器的数量相同。

如果有超过 8 个逻辑处理器,则将 n 的值设置为逻辑处理器的大约 5/8。这在大多数情况下都有效,但较大的 SPARC 系统除外,其中 n 的值可能约为逻辑处理器的 5/16。

-XX:ConcGCThreads=n

设置并行标记线程的数量。将 n 设置为并行垃圾回收线程 (ParallelGCThreads) 数量的大约 1/4。

-XX:InitiatingHeapOccupancyPercent=45

设置触发标记周期的 Java 堆占用阈值。默认占用率为整个 Java 堆的 45%。

-XX:G1MixedGCLiveThresholdPercent=65

设置要包含在混合垃圾回收周期中的旧区域的占用阈值。默认占用率为 65%

-XX:G1HeapWastePercent=10

设置您愿意浪费的堆百分比。当可回收百分比小于堆浪费百分比时,Java HotSpot VM 不会启动混合垃圾回收周期

-XX:G1MixedGCCountTarget=8

设置标记周期后混合垃圾收集的目标数量,以收集最多具有 G1MixedGCLiveThresholdPercent 实时数据的旧区域。默认为 8 次混合垃圾回收

-XX:G1OldCSetRegionThresholdPercent=10

设置在混合垃圾收集周期期间要收集的旧区域数量的上限。默认值为 Java 堆的 10%

-XX:G1ReservePercent=10

设置保留内存的百分比以保持空闲,以降低 to-space 溢出的风险。默认值为 10%。当您增加或减少百分比时,请确保将总 Java 堆调整相同的数量。

您重新配置了许多 G1GC 参数,如果您按照上述文档页面操作,则不需要这些参数。请仔细检查上述建议,尤其是基于您的 CPU 内核的 ParallelGCThreads 和 ConcGCThreads。删除不必要参数的重新配置。

Recommendations 来自甲骨文:

当您评估和微调 G1 GC 时,请牢记以下建议:

年轻代大小:避免使用 -Xmn 选项或任何或其他相关选项(例如 -XX:NewRatio)显式设置年轻代大小。固定年轻代的大小会覆盖目标暂停时间目标。暂停时间目标:当您评估或调整任何垃圾收集时,总是需要在延迟与吞吐量之间进行权衡。 G1 GC 是一种具有统一暂停的增量垃圾收集器,但应用程序线程的开销也更大。 G1 GC 的吞吐量目标是 90% 的应用程序时间和 10% 的垃圾收集时间。

Java 7 中的 cms 或并行收集器等其他收集器是否有任何更改?

Java 7 有一些变化。看看这个article

我在哪里可以找到关于 Java 7 中垃圾收集的优秀文档?

请参阅有关 gc 和相关 SE 问题的 oracle 文档页面:

Java G1 garbage collection in production


N
Nitan S. Kotwal

没有 G1 不是 jdk 1.7.0_02 中的默认垃圾收集器。默认的垃圾收集器取决于机器的类别。如果机器是 Server 类,那么默认的垃圾收集器是吞吐量收集器。如果机器是客户端类,那么默认的垃圾收集器是串行收集器。


我认为这是完全正确的。 Java 5 reference,仍然有效。在 Windows 系统 (32/64) 上:运行 Java 32 位 (5..8) >>默认情况下是串行 GC。运行 Java 64 位 (5..6) >>默认为 ParallelGC(仅限年轻一代)。运行 Java 64 位 (7..8) >>默认为 ParallelOldGC(年轻和老年代并行)。 Reference for Java 7 change,最后是 'parallel' collector == 'throughput' collector"
(对这个人的第一个准确的 SO 贡献的严厉回应。我注意到这也是他们的最后一个。)
I
IceMan

http://www.oracle.com/technetwork/java/javase/tech/g1-intro-jsp-135488.html 提供的文档(Wojtek 提供的链接)似乎是唯一的官方信息链接,但该信息似乎已过时,因为提到的一些标志仅在测试版本中可用,它们不再存在于生产中发布。 Oracle 的一些人应该提供一些关于 G1 GC 的更新文档。


Z
Zoltan Juhasz

默认情况下,您并不想使用 G1 收集器,因为它并不比其他收集器更好。它只适用于特殊用途。

在低延迟应用程序中,它比 CMS 略好,因为它的暂停时间更短,更可预测。作为交换,吞吐量比 CMS 差得多。

所以只有延迟很重要才好,但吞吐量根本不重要。如果两者都很重要,那么请继续使用 CMS。