Java Reference
In-Depth Information
from native code. (The not-so-simple way is to explicitly construct a Throwable
object and provide it a cause. Then use the JNI Throw() function.)
For special needs, you can define custom Exception classes in Java that
extend java.lang.Exception .Ifacustom exception can be found in the
CLASSPATH , then FindClass() can find it and native code can throw the
custom exception just as well as the standard Java library exceptions.
22.11 Local and global references
The JVM must keep track of references to all Java objects passed to native code,
primarily so the Java garbage collector does not arbitrarily free an object while
it is in use in the native code. There are two basic types of references to objects
used by native code: local and global references.
Local references are valid only during the duration of the native method call.
They are freed automatically upon return from native code to Java. Global ref-
erences exist even after the native method goes out of scope. Global references
must be freed explicitly by the programmer when no longer needed.
All objects are passed to native code as local references, and all objects created
within the native code by JNI functions such as NewStringUTF() are created
as local references. This arrangement is normal and expected. When the native
method returns, the local references are deleted, permitting the garbage collector
to free the memory associated with those objects if needed (and, of course, if
there are no outstanding references still in use on the Java side).
For special needs, JNI permits you to create global references from local
references with the NewGlobalRef() function. If a global reference is created,
then it is vital that DeleteGlobalRef() be called when the global reference
is no longer needed. Otherwise, a memory leak and/or heap fragmentation can
occur as the Java garbage collector is never able to free or move the memory
associated with the global reference.
A tempting but mistaken tactic is to attempt to cache a jclass across native
method invocations in order to save the cost of the call to GetObjectClass()
or FindClass() . Under normal circumstances, the jclass is a local reference
and so it becomes no longer valid after the first native method returns. An attempt
to use the cached value on a subsequent call to the native method produces
unpredicatable results, possibly including a JVM crash.
A related mistake is to attempt to cache method or field IDs, probably in an
attempt to save the cost of calling GetMethodID() or GetFieldID() .Itturns
out that method and field IDs are valid only as long as the class from which the
ID is derived is not unloaded. After a native method returns to Java code, the Java
garbage collector could possibly unload the class to which the IDs refer. If so,
then subsequent use of the cached IDs can result in unpredictable behavior.
To solve the latter problem it is safest to re-compute the field or method
IDs when needed again. Another solution is to create a global reference to the
jclass that remains valid even after the native method goes out of scope. Since
Search WWH ::




Custom Search