Name: vrR10176 Date: 02/07/2002
JNI function EnsureLocalCapacity() does not work properly and
it looks like EnsureLocalCapacity() returns always 0.
JNI Enhancements Introduced in version 1.2 of the JavaTM 2 SDK
(http://java.sun.com/j2se/1.4/docs/guide/jni/jni-12.html) says
about the function:
"jint EnsureLocalCapacity(JNIEnv *env, jint capacity);
Ensures that at least a given number of local references can
be created in the current thread. Returns 0 on success; otherwise
returns a negative number and throws an OutOfMemoryError. ..."
If the function is provided with capacity set to Integer.MAX_VALUE
value, EnsureLocalCapacity() returns 0, it means a given huge number
of local references can be created. But if JVM tries to create these
references, it crashes with OutOfMemoryError when the memory is
exhausted. This means the function ensures nothing.
BTW. If the function is provided with capacity set to negative value,
EnsureLocalCapacity() returns 0, it means given negative number of
local references can be created, it is a strange result, although
the specification does not specify appropriate capacity values.
To reproduce the issue execute the following test.
Test provides EnsureLocalCapacity() with some capacity values
and prints the return values. After this test tries to create
Integer.MAX_VALUE/2 local references.
------------ enlctest.java -------------------------------
import java.io.PrintStream;
public class enlctest {
native int createRefs(int capac);
native int funEnsureLocalCapacity(int capacity);
static {
try {
System.loadLibrary("jnitest");
} catch (Throwable e) {
System.out.println( e + " was thrown");
}
}
public static void main(String argv[]) {
enlctest tob = new enlctest();
try {
System.out.println("capacity=-1, EnsureLocalCapacity returns " + tob.funEnsureLocalCapacity(-1));
System.out.println("capacity=0, EnsureLocalCapacity returns " + tob.funEnsureLocalCapacity(0));
System.out.println("capacity=17, EnsureLocalCapacity returns " + tob.funEnsureLocalCapacity(17));
System.out.println("capacity=" + Integer.MAX_VALUE + "(Integer.MAX_VALUE), EnsureLocalCapacity returns " +
tob.funEnsureLocalCapacity(Integer.MAX_VALUE));
System.out.println("capacity=" + Integer.MIN_VALUE + "(Integer.MIN_VALUE), EnsureLocalCapacity returns " +
tob.funEnsureLocalCapacity(Integer.MIN_VALUE));
} catch (OutOfMemoryError e) {
System.out.println( e + " was thrown");
} catch (Throwable e) {
System.out.println( e + " was thrown");
}
try {
float coef = 0.5F;
int res = tob.createRefs((int)(Integer.MAX_VALUE*coef));
System.out.println("res: " + res);
} catch (Throwable e) {
System.out.println( e + " was thrown");
}
}
}
------------ enlctest.c ----------------------------------
#include "jni.h"
JNIEXPORT jint JNICALL Java_enlctest_funEnsureLocalCapacity(JNIEnv *env, jobject obj, jint capacity) {
return (*env) -> EnsureLocalCapacity(env, capacity);
}
JNIEXPORT jint JNICALL Java_enlctest_createRefs(JNIEnv *env, jobject obj, jint capacity) {
jint i;
jobject dummy_obj;
i = (*env) -> EnsureLocalCapacity(env, capacity);
if (i != 0) {
return i;
}
for (i = 0; i < capacity; i++) {
dummy_obj = (*env) -> NewLocalRef(env, obj);
if (dummy_obj == NULL) {
return i;
}
if ((*env) -> ExceptionCheck(env)) {
return i;
}
}
return i;
}
------------ Logs ----------------------------------------
% ls -1
enlctest.c
enlctest.java
jni.h
jni_md.h
%javac -d . enlctest.java
%
%cc -G -KPIC -o libjnitest.so enlctest.c
%
%java -version
java version "1.4.0-rc"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-rc-b90)
Java HotSpot(TM) Client VM (build 1.4.0-rc-b90, mixed mode)
%
% java -Xfuture enlctest
capacity=-1, EnsureLocalCapacity returns 0
capacity=0, EnsureLocalCapacity returns 0
capacity=17, EnsureLocalCapacity returns 0
capacity=2147483647(Integer.MAX_VALUE), EnsureLocalCapacity returns 0
capacity=-2147483648(Integer.MIN_VALUE), EnsureLocalCapacity returns 0
Exception in thread "main" java.lang.OutOfMemoryError: requested 152 bytes
%
----------------------------------------------------------
======================================================================