如何知道G1垃圾收集器使用的区域大小?

16

我目前正在研究Java 8的最新版本中的G1垃圾回收器。

我遇到了“巨型分配”问题,想知道我的区域大小是多少。

我该如何找出设置的区域大小?

我该如何自行计算区域大小?

谢谢。

5个回答

30

Java-8中的G1区域大小基于startingHeapSize/2048并向下舍入到介于1MB和32MB之间第一个2的幂次;不支持小于1MB或大于32MB的区域大小。

您还可以通过-XX:G1HeapRegionSize=n设置区域大小(注意,该值具有相同的2的幂次/范围限制)。

因此,实际上JVM似乎偏向于区域计数介于2048和4095之间(假设堆大小介于2GB和128GB之间)。

通常,以下是每个堆大小范围的区域大小:

 <4GB -  1MB
 <8GB -  2MB
<16GB -  4MB
<32GB -  8MB
<64GB - 16MB
64GB+ - 32MB

注意,MB实际上是MiB,GB实际上是GiB。


1
尝试使用 jmap -heap pid - chengzi

3
JVM在启动时根据堆的大小计算出区域大小。堆的默认值为物理内存的1/4或1GB(以较小者为准)。请参阅此文
区域大小可以从1 MB到32 MB不等,具体取决于堆的大小。目标是不超过2048个区域。
您可以通过在启动脚本中指定-XX:G1HeapRegionSize=XX来覆盖大小。

Xms,最小堆: “目标是基于最小Java堆大小拥有约2048个区域。” 但如果未定义,则文档中未提及任何内容 :( - Zedorg

3

关于“我如何找出区域大小设置多大?”,您可以在启动Java时使用-Xlog:gc*标志(Java 9或更高版本),它应该会在最开始的时候打印:

[0.003s][info][gc,heap] Heap region size: 1M
[0.004s][info][gc     ] Using G1
[0.004s][info][gc,heap,coops] Heap address: 0x00000000fc000000, size: 64 MB, Compressed Oops mode: 32-bit

2

如果你想查看区域大小,请使用jinfo -flags your_pid

Non-default VM flags: -XX:G1HeapRegionSize=1048576 -XX:InitialHeapSize=1054867456 -XX:MarkStackSize=4194304 -XX:MaxHeapSize=5368709120 -XX:MaxNewSize=3221225472 -XX:MinHeapDeltaBytes=1048576 -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC 

0
  1. jps 查找 Java 程序的进程 ID
  2. jmap -heap pid
  3. G1HeapRegionSize 是 JVM 计算的区域大小

例如:

using thread-local object allocation.
Garbage-First (G1) GC with 8 thread(s)

Heap Configuration:
   MinHeapFreeRatio         = 30
   MaxHeapFreeRatio         = 50
   .............................
   MaxHeapSize              = 12884901888 (12288.0MB)
   G1HeapRegionSize         = 4194304 (4.0MB)

Heap Usage:
G1 Heap:
   regions  = 3072
   capacity = 12884901888 (12288.0MB)
   used     = 4050405416 (3862.7676162719727MB)
   free     = 8834496472 (8425.232383728027MB)
   31.435283335546654% used

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