ZGC: Robust NUMA configuration detection

XMLWordPrintable

    • Type: Bug
    • Resolution: Fixed
    • Priority: P2
    • 26
    • Affects Version/s: 25
    • Component/s: hotspot
    • gc
    • b21
    • linux

      When page allocation was overhauled in JDK-8350441, NUMA support in ZGC was also significantly overhauled. The concept of a partition was introduced as a one-to-one mapping between NUMA nodes and a subset of the Java heap. The number of partitions is ideally the same number of NUMA nodes the Java process is bound to use.

      Using ZGC and binding the Java process to only use a subset of the available NUMA nodes on a system with more than 2 NUMA nodes, there will be a mismatch between the internal representation and the configured one. The internal representation ends up having as many partitions as there are NUMA nodes on the system, not how many NUMA nodes the Java process will actually use.

      For example, on a system with 4 NUMA nodes, each partition will have a capacity of 1/4 of -Xmx. If the Java process is configured to only use two of those four nodes, each partition should really have 1/2 of -Xmx instead. If the Java process uses more memory than is available on the nodes it has configured, memory on the "unconfigured" nodes will be used instead, which circumvents the configuration all together

      For example, binding the Java process to used nodes 0 and 2 on a system with 4 NUMA nodes will report that 4 NUMA nodes are used and we can also see that memory is allocated on all four nodes.
      $ numactl --cpunodebind=0,2 --membind=0,2 ./jdk-25/bin/java -Xms200M -Xmx200M -XX:+AlwaysPretouch -XX:+UseZGC -Xlog:gc+init -Xlog:os Forever.java
      [0.236s][info][gc,init] NUMA Support: Enabled
      [0.237s][info][gc,init] NUMA Nodes: 4

      $ cat /proc/$(pidof java)/numa_maps | grep java_heap
      40000000000 bind:0,2 file=/memfd:java_heap\040(deleted) dirty=12800 active=0 N0=12800 kernelpagesize_kB=4
      401f1000000 bind:0,2 file=/memfd:java_heap\040(deleted) dirty=12800 active=0 N1=12800 kernelpagesize_kB=4
      403e2000000 bind:0,2 file=/memfd:java_heap\040(deleted) dirty=12800 active=0 N2=12800 kernelpagesize_kB=4
      405d3000000 bind:0,2 file=/memfd:java_heap\040(deleted) dirty=12800 active=0 N3=12800 kernelpagesize_kB=4

            Assignee:
            Joel Sikström
            Reporter:
            Joel Sikström
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: