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

Java 7 (JDK 7) garbage collection and documentation on G1

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

我的问题:

  • G1是Java 7中的默认收集器,如果不是,我如何激活G1?
  • g7在Java7中有哪些可选设置?
  • 是否对Java 7中的其他收集器(如cms或并行收集器)进行了更改?
  • 在哪里可以找到有关Java 7中垃圾收集的好文档?

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    > 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收集器,但是:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    > 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.

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


    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中的并行收集器。


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

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

    Using G1 G1 is still considered experimental and can be enabled with
    the following two parameters:

    -XX:+UnlockExperimentalVMOptions -XX:+UseG1GC

    To set a GC pause time goal, use the following parameter:

    -XX:MaxGCPauseMillis =50 (for a pause time target of 50ms)

    With G1, a time interval can be specified during which a GC pause
    should last no longer than the time given above:

    -XX:GCPauseIntervalMillis =200 (for a pause interval target of 200ms)

    Note that the above two options represent goals, not promises or
    guarantees. They might work well in some situations but not in others,
    and the GC might not always be able to obey them.

    Alternatively, the size of the young generation can be specified
    explicitly to impact evacuation pause times:

    -XX:+G1YoungGenSize=512m (for a 512 megabyte young generation)

    G1 also uses the equivalent of survivor spaces, which are, naturally,
    a set of (potentially non-contiguous) regions. Their size can be
    specified with the usual parameters (e.g., -XX:SurvivorRatio=6).

    Finally, to run G1 at its full potential, try setting these two
    parameters which are currently disabled by default because they may
    uncover a rare race condition:

    -XX:+G1ParallelRSetUpdatingEnabled -XX:+G1ParallelRSetScanningEnabled

    One more thing to note is that G1 is very verbose compared to other
    HotSpot GCs when -XX:+PrintGCDetails is set. This is because it prints
    per-GC-thread timings and other information very helpful in profiling
    and trouble-shooting. If you want a more concise GC log, please switch
    to using -verbosegc (though it is recommended that the more detailed
    GC log be obtained).

    我也发现这篇文章对于理解G1的内部非常有帮助。

    这里有更多信息。


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

    此Java 5页面上的规则仍适用于Java 7(和AFAIK,Java 8):

    On server-class machines running the server VM, the garbage collector (GC) has changed from the previous serial collector (-XX:+UseSerialGC) to a parallel collector (-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:+UseG1GC。也许你感兴趣的是你想??要:

    Applications running today with either the CMS or the ParallelOld garbage collector would benefit switching to G1 if the application has one or more of the following traits.

    • More than 50% of the Java heap is occupied with live data.
    • The rate of object allocation rate or promotion varies significantly.
    • Undesired long garbage collection or compaction pauses (longer than 0.5 to 1 second)

    2. g7在Java7中有哪些可选设置?

    我自己没有使用G1,但我认为它坚持使用与调整其他并行收集器相同的基本"吞吐量/人体工程学"标志。根据我对Parallel GC的经验,-XX:GCTimeRatio一直是提供预期的速度 - 内存权衡的关键因素。因人而异。

    此处列出了G1特定选项

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

    不知道,但......

    G1 is planned as the long term replacement for the Concurrent Mark-Sweep Collector (CMS)

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

    找到它可能是一种痛苦,不是吗?可能我发现的最好的"中心"页面是这个:

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

    需要一些深度阅读,但如果你需要做一些调整,值得花时间。特别有见地的是:垃圾收集器人体工程学


  • Is G1 the default collector in Java 7 and if not how do I activate G1?
  • G1不是Java 7中的默认收集器。-XX:+UseG1GC将启用G1GC

  • What optional settings does g1 have in Java7?
  • 有许多。有关完整信息,请查看此oracle文章。

    The G1 GC is an adaptive garbage collector with defaults that enable it to work efficiently without modification.

    Ok.

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

    1
    2
    3
    4
    -XX:MaxGCPauseMillis
    -XX:G1HeapRegionSize
    -XX:ParallelGCThreads
    -XX:ConcGCThreads

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

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

    重要默认值:

    1
    -XX:G1HeapRegionSize=n

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

    1
    -XX:MaxGCPauseMillis=200

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

    1
    -XX:G1NewSizePercent=5

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

    1
    -XX:G1MaxNewSizePercent=60

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

    1
    -XX:ParallelGCThreads=n

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

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

    1
    -XX:ConcGCThreads=n

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

    1
    -XX:InitiatingHeapOccupancyPercent=45

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

    1
    -XX:G1MixedGCLiveThresholdPercent=65

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

    1
    -XX:G1HeapWastePercent=10

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

    1
    -XX:G1MixedGCCountTarget=8

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

    1
    -XX:G1OldCSetRegionThresholdPercent=10

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

    1
    -XX:G1ReservePercent=10

    设置保留空闲的百分比以保持空闲,从而降低空间溢出的风险。默认值为10%。增加或减少百分比时,请确保将总Java堆调整相同的量。

    您已重新配置了许多G1GC参数,如果您按照上述文档页面进行操作,则不需要这些参数。请交叉检查以上建议,特别是ParallelGCThreads和ConcGCThreads,它们将基于您的CPU核心。删除不必要参数的重新配置。

    来自oracle的建议:

    在评估和微调G1 GC时,请记住以下建议:

  • 年轻代大小:避免使用-Xmn选项或任何或其他相关选项(如-XX:NewRatio)明确设置年轻代大小。修复年轻一代的大小会覆盖目标暂停时间目标。

  • 暂停时间目标:评估或调整任何垃圾收集时,始终存在延迟与吞吐量的权衡。 G1 GC是一个增量垃圾收集器,具有统一的暂停,但在应用程序线程上也有更多的开销。 G1 GC的吞吐量目标是90%的应用程序时间和10%的垃圾回收时间。

  • Were there any changes made to other collectors like cms or the parallel collector in Java 7?
  • Java 7有一些变化。看看这篇文章

  • Where can I find good documentation on garbage collection in Java 7?
  • 有关gc和相关SE问题,请参阅oracle文档页面:

    生产中的Java G1垃圾收集

    好。


    没有G1不是jdk 1.7.0_02中的默认垃圾收集器。
    默认的垃圾收集器取决于计算机的类。
    如果计算机属于Server类,则默认垃圾回收器为吞吐量收集器。
    如果计算机是Client类,则默认的垃圾收集器是Serial Collector。


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


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

    在低延迟应用程序中,它比CMS更好,因为它有一点点更短,更可预测的暂停时间。作为交换,吞吐量比CMS更糟糕。

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