G1 GC 分配的内存大于堆大小
G1 GC allocated memory is more than heap size
我为应用程序服务器更改了 GC。现在我使用 G1 GC。我有 30 GB 内存。对于初始测试,我仅将 Xms 和 Xmx 值设置为相同 23040 mb.
我使用的设置:
-Xms23040m -Xmx23040m -XX:+UseG1GC -XX:MetaspaceSize=512M -XX:MaxMetaspaceSize=1536m
如果我使用 G1 GC,我会有有趣的 GCEasy 指标。
Generation | Allocated | Peak
Young Gen | 13.38 | 3.37
Old Gen | 21.17 | 485mb
Meta Space | 1.5 | n/a
Young + old + Meta | 23.78 | 13.61
总计 36.05 GB 怎么得来的? GCEasy 图 link is here.
我不明白为什么分配的内存大于最大堆大小?
GC初始日志:
OpenJDK 64-Bit Server VM (25.282-b08) for linux-amd64 JRE (1.8.0_282-b08), built on Jan 20 2021 11:56:52 by "jenkins" with gcc 7.5.0
Memory: 4k page, physical 31389860k(23816948k free), swap 0k(0k free)
CommandLine flags: -XX:GCLogFileSize=3145728 -XX:InitialHeapSize=23923261440 -XX:MaxHeapSize=23923261440 -XX:MaxMetaspaceSize=1610612736 -XX:MetaspaceSize=536870912 -XX:NumberOfGCLogFiles=5 -XX:+PrintGC -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:-TraceClassUnloading -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC -XX:+UseGCLogFileRotation
GC 暂停日志:
2022-01-19T08:18:40.340-0500: 45739.624: [GC pause (G1 Evacuation Pause) (young), 0.0675291 secs]
[Parallel Time: 42.0 ms, GC Workers: 1]
[GC Worker Start (ms): 45739624.2]
[Ext Root Scanning (ms): 10.8]
[Update RS (ms): 5.1]
[Processed Buffers: 76]
[Scan RS (ms): 2.1]
[Code Root Scanning (ms): 2.9]
[Object Copy (ms): 21.0]
[Termination (ms): 0.0]
[Termination Attempts: 1]
[GC Worker Other (ms): 0.0]
[GC Worker Total (ms): 41.9]
[GC Worker End (ms): 45739666.1]
[Code Root Fixup: 0.0 ms]
[Code Root Purge: 0.0 ms]
[Clear CT: 5.8 ms]
[Other: 19.7 ms]
[Choose CSet: 0.0 ms]
[Ref Proc: 16.8 ms]
[Ref Enq: 0.1 ms]
[Redirty Cards: 0.1 ms]
[Humongous Register: 0.1 ms]
[Humongous Reclaim: 0.0 ms]
[Free CSet: 2.3 ms]
[Eden: 13632.0M(13632.0M)->0.0B(13632.0M) Survivors: 57344.0K->57344.0K Heap: 13933.2M(22816.0M)->307.2M(22816.0M)]
[Times: user=0.07 sys=0.00, real=0.07 secs]
这是否意味着 GCEasy.io 存在无法显示正确指标的错误?当我使用 Parallel GC 时,我没有遇到类似的问题。 (分配的内存比 Xmx 不多)
table 中列出的分配大小包括 Metaspace。元空间是与 java 对象堆分开的内存池。因此堆和元空间的总和可以超过最大堆大小。
[Eden: 13632.0M(13632.0M)->0.0B(13632.0M) Survivors: 57344.0K->57344.0K Heap: 13933.2M(22816.0M)->307.2M(22816.0M)]
这表明总体堆大小(所有代)为 ~22GB,在最大堆限制内。也许 gceasy 将总堆大小误认为是老年代?
这是你的JVM参数,数字是byte。 23923261440(字节)= 22815(Mb)= 22.28(Gb)
-XX:InitialHeapSize=23923261440
-XX:MaxHeapSize=23923261440
默认情况下,G1的Young Gen
和Old Gen
的space不是fixed.From您分享的GCEasy页面的Interactive Graphs
栏,
我将以下信息整理成时间线。
GC Times
Young Gen(Mb)
Old Gen(Mb)
Total(Mb)
First
1232
21584
22816
Fifth
1136
21680
22816
33th
5384
17432
22816
35th
1200
21616
22816
53th
13696
9120
22816
Last
13688
9128
22816
根据以上table可以得出以下结论:
- 如果设置
-Xms
与-Xmx
一致,则Young Gen
加Old Gen
为固定值
Young Gen
space一直在变化,有时增加,有时减少。 old Gen
相反。
在G1中,Young Gen
的space在GC之后一直在变化,Parallel GC
中的Young Gen
的space总是固定的。
因此GCEasy无法用唯一的值来表示G1的每个gen
的分配space,所以它选择取每个Gen
申请期间的最大值 运行。根据上面的table,space计算如下:
Young Gen
的最大值为:13696(Mb) = 13.375(Gb) ≈ 13.38(Gb)
Old Gen
的最大值为:21680(Mb) = 21.171(Gb)≈21.17(Gb)
两个值的近似值与下面的table完全吻合。
Generation
Allocated
Peak
Young Gen
13.38
3.37
Old Gen
21.17
485mb
Meta Space
1.5
n/a
Young + old + Meta
23.78
13.61
我为应用程序服务器更改了 GC。现在我使用 G1 GC。我有 30 GB 内存。对于初始测试,我仅将 Xms 和 Xmx 值设置为相同 23040 mb.
我使用的设置:
-Xms23040m -Xmx23040m -XX:+UseG1GC -XX:MetaspaceSize=512M -XX:MaxMetaspaceSize=1536m
如果我使用 G1 GC,我会有有趣的 GCEasy 指标。
Generation | Allocated | Peak
Young Gen | 13.38 | 3.37
Old Gen | 21.17 | 485mb
Meta Space | 1.5 | n/a
Young + old + Meta | 23.78 | 13.61
总计 36.05 GB 怎么得来的? GCEasy 图 link is here.
我不明白为什么分配的内存大于最大堆大小?
GC初始日志:
OpenJDK 64-Bit Server VM (25.282-b08) for linux-amd64 JRE (1.8.0_282-b08), built on Jan 20 2021 11:56:52 by "jenkins" with gcc 7.5.0
Memory: 4k page, physical 31389860k(23816948k free), swap 0k(0k free)
CommandLine flags: -XX:GCLogFileSize=3145728 -XX:InitialHeapSize=23923261440 -XX:MaxHeapSize=23923261440 -XX:MaxMetaspaceSize=1610612736 -XX:MetaspaceSize=536870912 -XX:NumberOfGCLogFiles=5 -XX:+PrintGC -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:-TraceClassUnloading -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC -XX:+UseGCLogFileRotation
GC 暂停日志:
2022-01-19T08:18:40.340-0500: 45739.624: [GC pause (G1 Evacuation Pause) (young), 0.0675291 secs]
[Parallel Time: 42.0 ms, GC Workers: 1]
[GC Worker Start (ms): 45739624.2]
[Ext Root Scanning (ms): 10.8]
[Update RS (ms): 5.1]
[Processed Buffers: 76]
[Scan RS (ms): 2.1]
[Code Root Scanning (ms): 2.9]
[Object Copy (ms): 21.0]
[Termination (ms): 0.0]
[Termination Attempts: 1]
[GC Worker Other (ms): 0.0]
[GC Worker Total (ms): 41.9]
[GC Worker End (ms): 45739666.1]
[Code Root Fixup: 0.0 ms]
[Code Root Purge: 0.0 ms]
[Clear CT: 5.8 ms]
[Other: 19.7 ms]
[Choose CSet: 0.0 ms]
[Ref Proc: 16.8 ms]
[Ref Enq: 0.1 ms]
[Redirty Cards: 0.1 ms]
[Humongous Register: 0.1 ms]
[Humongous Reclaim: 0.0 ms]
[Free CSet: 2.3 ms]
[Eden: 13632.0M(13632.0M)->0.0B(13632.0M) Survivors: 57344.0K->57344.0K Heap: 13933.2M(22816.0M)->307.2M(22816.0M)]
[Times: user=0.07 sys=0.00, real=0.07 secs]
这是否意味着 GCEasy.io 存在无法显示正确指标的错误?当我使用 Parallel GC 时,我没有遇到类似的问题。 (分配的内存比 Xmx 不多)
table 中列出的分配大小包括 Metaspace。元空间是与 java 对象堆分开的内存池。因此堆和元空间的总和可以超过最大堆大小。
[Eden: 13632.0M(13632.0M)->0.0B(13632.0M) Survivors: 57344.0K->57344.0K Heap: 13933.2M(22816.0M)->307.2M(22816.0M)]
这表明总体堆大小(所有代)为 ~22GB,在最大堆限制内。也许 gceasy 将总堆大小误认为是老年代?
这是你的JVM参数,数字是byte。 23923261440(字节)= 22815(Mb)= 22.28(Gb)
-XX:InitialHeapSize=23923261440
-XX:MaxHeapSize=23923261440
默认情况下,G1的Young Gen
和Old Gen
的space不是fixed.From您分享的GCEasy页面的Interactive Graphs
栏,
我将以下信息整理成时间线。
GC Times | Young Gen(Mb) | Old Gen(Mb) | Total(Mb) |
---|---|---|---|
First | 1232 | 21584 | 22816 |
Fifth | 1136 | 21680 | 22816 |
33th | 5384 | 17432 | 22816 |
35th | 1200 | 21616 | 22816 |
53th | 13696 | 9120 | 22816 |
Last | 13688 | 9128 | 22816 |
根据以上table可以得出以下结论:
- 如果设置
-Xms
与-Xmx
一致,则Young Gen
加Old Gen
为固定值 Young Gen
space一直在变化,有时增加,有时减少。old Gen
相反。
在G1中,Young Gen
的space在GC之后一直在变化,Parallel GC
中的Young Gen
的space总是固定的。
因此GCEasy无法用唯一的值来表示G1的每个gen
的分配space,所以它选择取每个Gen
申请期间的最大值 运行。根据上面的table,space计算如下:
Young Gen
的最大值为:13696(Mb) = 13.375(Gb) ≈ 13.38(Gb)Old Gen
的最大值为:21680(Mb) = 21.171(Gb)≈21.17(Gb)
两个值的近似值与下面的table完全吻合。
Generation | Allocated | Peak |
---|---|---|
Young Gen | 13.38 | 3.37 |
Old Gen | 21.17 | 485mb |
Meta Space | 1.5 | n/a |
Young + old + Meta | 23.78 | 13.61 |