RFR: 8187450: JNI local refs exceeds capacity warning in NetworkInterface::getAll

Jonathan Dowland jdowland at openjdk.java.net
Fri Mar 12 14:46:16 UTC 2021


This is an adaptation of a patch originally written by Shafi Ahmad in
a comment on the JBS page but never submitted or merged.

With -Xcheck:jni, the method java.net.NetworkInterface.getAll very
quickly breaches the default JNI local refs threshold (32). Exactly when
this happens depends upon the number of network interfaces (in state "UP")
visible to Java. On Linux, with current Trunk, 2 network interfaces is
sufficient to breach:

    $ ./addif.sh 0
    1 interfaces
    $ sudo ip netns exec jbase $JAVA_HOME/bin/java -Xcheck:jni NITest
     (nothing)
    $ ./addif.sh 1
    2 interfaces
    $ sudo ip netns exec jbase $JAVA_HOME/bin/java -Xcheck:jni NITest
    WARNING: JNI local refs: 33, exceeds capacity: 32
            at java.net.NetworkInterface.getAll(java.base/Native Method)
            at java.net.NetworkInterface.getNetworkInterfaces(java.base/NetworkInterface.java:351)
            at NITest.main(NITest.java:3)

This patch improves the situation:

    $ ./addif.sh 3
    4 interfaces
    $ sudo ip netns exec jbase $JAVA_HOME/bin/java -Xcheck:jni NITest
     (nothing)
    $ ./addif.sh 4
    5 interfaces
    $ sudo ip netns exec jbase $JAVA_HOME/bin/java -Xcheck:jni NITest
    WARNING: JNI local refs: 33, exceeds capacity: 32
            at java.net.NetworkInterface.getAll(java.base/Native Method)
            at java.net.NetworkInterface.getNetworkInterfaces(java.base/NetworkInterface.java:351)
            at NITest.main(NITest.java:3)


Once the JNI local refs threshold is breached, the threshold is raised.
With the patch, it takes 10 network interfaces to breach the new
threshold 

    $ ./addif.sh 9
    10 interfaces
    $ sudo ip netns exec jbase $JAVA_HOME/bin/java -Xcheck:jni NITest
    WARNING: JNI local refs: 33, exceeds capacity: 32
            at java.net.NetworkInterface.getAll(java.base/Native Method)
            at java.net.NetworkInterface.getNetworkInterfaces(java.base/NetworkInterface.java:351)
            at NITest.main(NITest.java:3)
    WARNING: JNI local refs: 66, exceeds capacity: 65
            at java.net.NetworkInterface.getAll(java.base/Native Method)
            at java.net.NetworkInterface.getNetworkInterfaces(java.base/NetworkInterface.java:351)
            at NITest.main(NITest.java:3)

Without the patch it takes 5.

Helper scripts for testing on Linux. `setupnet.sh`:

    #!/bin/bash
    set -euo pipefail

    namespace=${namespace:-jbase}
    sudo ip netns add ${namespace}

And `addif.sh`:

    #!/bin/bash
    set -euo pipefail

    namespace=${namespace:-jbase}
    num="$1"

    sudo ip link add name vethhost${num} type veth peer name veth${namespace}${num}
    sudo ip link set veth${namespace}${num} netns ${namespace}
    sudo ip addr add 192.168.2.${num}/24 dev vethhost${num}
    sudo ip netns exec ${namespace} ip addr add 192.168.2.${num}/24 dev veth${namespace}${num}
    sudo ip link set vethhost${num} up
    sudo ip netns exec ${namespace} ip link set veth${namespace}${num} up

    count="$(sudo ip netns exec ${namespace} ip link show |grep UP | wc -l)"
    echo "${count} interfaces"

-------------

Commit messages:
 - 8187450: JNI local refs exceeds capacity warning in NetworkInterface::getAll

Changes: https://git.openjdk.java.net/jdk/pull/2963/files
 Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=2963&range=00
  Issue: https://bugs.openjdk.java.net/browse/JDK-8187450
  Stats: 18 lines in 2 files changed: 18 ins; 0 del; 0 mod
  Patch: https://git.openjdk.java.net/jdk/pull/2963.diff
  Fetch: git fetch https://git.openjdk.java.net/jdk pull/2963/head:pull/2963

PR: https://git.openjdk.java.net/jdk/pull/2963


More information about the net-dev mailing list