javagarbage-collectionjvmg1gcjava-heap

G1 GC allocated memory is more than heap size


I change GC for application server. Now I use G1 GC. I have 30 GB RAM. For initial testing I set only Xms and Xmx values to be the same 23040 mb.

Settings I use:

 -Xms23040m -Xmx23040m  -XX:+UseG1GC -XX:MetaspaceSize=512M -XX:MaxMetaspaceSize=1536m 

I have interesting GCEasy Metrics if I use G1 GC.

   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

Total is 36.05 GB How come? GCEasy Diagram link is here.

I don't understand why allocated Memory is more than Max heap size?

GC initial Log:

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 Pause log:

    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] 

Does it mean that GCEasy.io has bug to show correct metrics? I do not have similar issues when I use Parallel GC. (Allocated memory is not more than Xmx)


Solution

  • This is your JVM parameters ,the number is byte. 23923261440(byte) = 22815(Mb) = 22.28(Gb)

    -XX:InitialHeapSize=23923261440
    -XX:MaxHeapSize=23923261440
    

    By default, the space of G1's Young Gen and Old Gen is not fixed.From the Interactive Graphs column of the GCEasy page you shared, I have organized the following information in a timeline.

    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

    The following conclusions can be drawn from the table above:

    1. If -Xms is set and consistent with -Xmx, then Young Gen plus Old Gen will be a fixed value.
    2. The Young Gen space is always changing, sometimes increasing and sometimes decreasing. old Gen is the opposite.

    In G1, the space of Young Gen is always changing after GC, the space of Young Gen in Parallel GC is always fixed. Therefore, GCEasy cannot use a unique value to represent the allocation space of each gen of G1, so it chooses to take each Gen The maximum value during application running. According to the table above, the space is calculated as follows:

    The approximation of the two values exactly matches the table below.

    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