Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8314940

Use of NIO in JDKs Metrics implementation causes issues in GraalVM

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Won't Fix
    • Icon: P3 P3
    • 22
    • 11.0.20, 17.0.8, 21, 22
    • core-svc
    • generic
    • linux

      This code:

      public class MaxMemTest {
      public static void main(String[] args) {
      long maxMem = Runtime.getRuntime().maxMemory();
      System.out.println("maxMem = " + maxMem);
      }
      }

      When compiled to a native-image using a GraalVM, then run it, results in this stack overflow:

        i SP 0x00007ffdf838e070 IP 0x00000000008bf8b9 size=16 java.nio.file.Files.readAllLines(Files.java:3433)
        i SP 0x00007ffdf838e070 IP 0x00000000008bf8b9 size=16 jdk.internal.platform.CgroupUtil.lambda$readAllLinesPrivileged$2(CgroupUtil.java:83)
        A SP 0x00007ffdf838e070 IP 0x00000000008bf8b9 size=16 jdk.internal.platform.CgroupUtil$$Lambda$a0a20a05f23dafb9435259313f4041cb74d30494.run(Unknown Source)
        A SP 0x00007ffdf838e080 IP 0x000000000068283e size=32 java.security.AccessController.executePrivileged(AccessController.java:114)
        A SP 0x00007ffdf838e0a0 IP 0x00000000006822b9 size=32 java.security.AccessController.doPrivileged(AccessController.java:571)
        A SP 0x00007ffdf838e0c0 IP 0x00000000008bfb19 size=48 jdk.internal.platform.CgroupUtil.readAllLinesPrivileged(CgroupUtil.java:84)
        A SP 0x00007ffdf838e0f0 IP 0x00000000008bc715 size=176 jdk.internal.platform.CgroupSubsystemFactory.determineType(CgroupSubsystemFactory.java:143)
        A SP 0x00007ffdf838e1a0 IP 0x00000000008bbe2d size=16 jdk.internal.platform.CgroupSubsystemFactory.create(CgroupSubsystemFactory.java:85)
        i SP 0x00007ffdf838e1b0 IP 0x0000000000414cb3 size=16 jdk.internal.platform.CgroupMetrics.getInstance(CgroupMetrics.java:193)
        i SP 0x00007ffdf838e1b0 IP 0x0000000000414cb3 size=16 jdk.internal.platform.SystemMetrics.instance(SystemMetrics.java:29)
        i SP 0x00007ffdf838e1b0 IP 0x0000000000414cb3 size=16 jdk.internal.platform.Metrics.systemMetrics(Metrics.java:58)
        i SP 0x00007ffdf838e1b0 IP 0x0000000000414cb3 size=16 jdk.internal.platform.Container.metrics(Container.java:43)
        A SP 0x00007ffdf838e1b0 IP 0x0000000000414cb3 size=16 com.oracle.svm.core.Containers.memoryLimitInBytes(Containers.java:121)
        A SP 0x00007ffdf838e1c0 IP 0x0000000000475885 size=16 com.oracle.svm.core.heap.PhysicalMemory.size(PhysicalMemory.java:92)
        A SP 0x00007ffdf838e1d0 IP 0x0000000000565153 size=32 java.lang.Runtime.maxMemory(Runtime.java:932)
        A SP 0x00007ffdf838e1f0 IP 0x00000000004792d3 size=16 com.oracle.svm.core.jdk.DirectMemoryAccessors.initialize(Target_jdk_internal_misc_VM.java:112)
        i SP 0x00007ffdf838e200 IP 0x0000000000671b1a size=80 com.oracle.svm.core.jdk.DirectMemoryAccessors.getPageAlignDirectMemory(Target_jdk_internal_misc_VM.java:94)
        i SP 0x00007ffdf838e200 IP 0x0000000000671b1a size=80 jdk.internal.misc.VM.isDirectMemoryPageAligned(VM.java:156)
        A SP 0x00007ffdf838e200 IP 0x0000000000671b1a size=80 java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:124)
        i SP 0x00007ffdf838e250 IP 0x0000000000903265 size=48 java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:360)
        A SP 0x00007ffdf838e250 IP 0x0000000000903265 size=48 sun.nio.ch.Util.getTemporaryDirectBuffer(Util.java:242)
        A SP 0x00007ffdf838e280 IP 0x00000000008ff35e size=80 sun.nio.ch.IOUtil.read(IOUtil.java:303)
        i SP 0x00007ffdf838e2d0 IP 0x00000000008fda4d size=96 sun.nio.ch.IOUtil.read(IOUtil.java:283)
        A SP 0x00007ffdf838e2d0 IP 0x00000000008fda4d size=96 sun.nio.ch.FileChannelImpl.read(FileChannelImpl.java:234)
        i SP 0x00007ffdf838e330 IP 0x00000000008f8946 size=64 sun.nio.ch.ChannelInputStream.read(ChannelInputStream.java:74)
        A SP 0x00007ffdf838e330 IP 0x00000000008f8946 size=64 sun.nio.ch.ChannelInputStream.read(ChannelInputStream.java:103)
        A SP 0x00007ffdf838e370 IP 0x000000000090601f size=64 sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:329)
        A SP 0x00007ffdf838e3b0 IP 0x00000000009052c3 size=48 sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:372)
        A SP 0x00007ffdf838e3e0 IP 0x0000000000905640 size=64 sun.nio.cs.StreamDecoder.lockedRead(StreamDecoder.java:215)
        A SP 0x00007ffdf838e420 IP 0x0000000000905ba9 size=64 sun.nio.cs.StreamDecoder.read(StreamDecoder.java:169)
        A SP 0x00007ffdf838e460 IP 0x00000000005281f5 size=16 java.io.InputStreamReader.read(InputStreamReader.java:188)
        A SP 0x00007ffdf838e470 IP 0x000000000051d331 size=48 java.io.BufferedReader.fill(BufferedReader.java:160)
        A SP 0x00007ffdf838e4a0 IP 0x000000000051d648 size=80 java.io.BufferedReader.implReadLine(BufferedReader.java:370)

      This is due to the following reasons:
      1. ByteBuffers in the JDK rely on Runtime.getRuntime().maxMemory() so as to determine the default max heap size being set.
      2. Runtime.getRuntime().maxMemory() implementation in GraalVM is internally relying on the JDK's Metrics implementation for its implementation to return the correct value even in containers.
      3. The JDK metrics implementation to use NIO itself, therefore introducing a cycle.

      A fairly straight forward fix for this would be to not rely on NIO in the JDK's Metrics implementation.

            sgehwolf Severin Gehwolf
            sgehwolf Severin Gehwolf
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: