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

Chris Hegarty chegar at openjdk.java.net
Mon Mar 15 17:16:14 UTC 2021


On Mon, 15 Mar 2021 16:59:24 GMT, Jonathan Dowland <jdowland at openjdk.org> wrote:

>> 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"
>
> Jonathan Dowland has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains one commit:
> 
>   8187450: JNI local refs exceeds capacity warning in NetworkInterface::getAll

src/java.base/windows/native/libnet/NetworkInterface.c line 677:

> 675:         (*env)->DeleteLocalRef(env, iaObj);
> 676:         (*env)->DeleteLocalRef(env, ibObj);
> 677:         (*env)->DeleteLocalRef(env, ia2Obj);

ia2Obj is not guaranteed to be set to a local reference, no? (if the address family is AF_INET6)

test/jdk/java/net/NetworkInterface/Test.java line 28:

> 26:  * @library /test/lib
> 27:  * @run main Test -Xcheck:jni
> 28:  * @run main/othervm -Djava.net.preferIPv4Stack=true Test -Xcheck:jni

You will need to put `-Xcheck:jni` before `Test` ( rather than after it ). Also make the first at run tag othervm also, since the test will now run with a command line argument.

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

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


More information about the net-dev mailing list