storing result of a Class getField call?

Tom Tromey tromey@redhat.com
Fri Jun 15 10:59:00 GMT 2001


>>>>> "Marcus" == Marcus G Daniels <mgd@swarm.org> writes:

Sorry about the delay in my reply.

Marcus> In some JNI code that works with Sun JDK 1.3 and Kaffe 1.0.6,
Marcus> I'm stashing the results of a Class getField call in a
Marcus> variable and globalrefing it.  By watching the unmark_for_gc
Marcus> call in jni.cc I can see that the reference to the Field is
Marcus> not explicitly removed from the JNI `ref_table', however, some
Marcus> time after caching the result of the getField call (when I
Marcus> wish to use and reuse and reuse the stashed Field), the object
Marcus> that is there has changed.

Offhand I couldn't say what is going on here.  Given that it works
when you disable GC, I would guess that the object is being collected.

This might happen if, for some reason, the `ref_table' is not being
scanned.

A few things I thought of that you could try:

* You could run your program in the debugger and put a finalizer on
  the Field which will cause an abort when it is finalized (see
  `fail_on_finalization' in prims.cc).
  If it is finalized then you'll know that it is being collected.

* You could try registering `ref_table' as a root in _Jv_JNI_Init.
  Initially you could do this just by calling the appropriate GC
  function directly.
  In theory this shouldn't be required though :-(

Marcus> Likewise, if I do a lookup of the Field immediately adjacent
Marcus> to the use I wish to make, it also works.

Marcus> It seems fishy that this last workaround works as well as it
Marcus> does if there is more general GC problem.

I'm not too suprised.  When you ask for a Field a new object is
created from the reflection data in the Class.  This reflection data
cannot be GCd; it is static.


If you could write a simple test case in the form of the tests in
gcc/libjava/testsuite/libjava.jni, I could check it in and perhaps
investigate it.

Tom



More information about the Java mailing list