Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

If JNI DeleteGlobalRef() is called, does the corresponding java object get garbage collected?

What I mean is, if I create a global reference jobject in C++, and then pass that off to some Java code, and delete call DeleteGlobalRef(), is that underlying java object potentially garbage collected right away, so that any future Java code that is already refering to that object might come back with a NullPointerException? Specifically, if I have some C++ code that does something like this simplified example:

static jobject myObjGlobalRef;
static JNIEnv* env = /* call to create a JVM and get the JNI env */;
jobject ReturnMyObj()
{
    /* <<Code that defines class, constructorId, and param1 goes here>> */

    jobject localObj = env->NewObject(class, constructorId, param1);
    myObjGlobalRef = env->NewGlobalRef(localObj);
}

void DeleteMyObj()
{
    env->DeleteGlobalRef(myObjGlobalRef);
}

myObjGlobalRef = ReturnMyObj();

jobject otherExistingGlobalRef = /* Assume we get another global ref to another parent obj somewhere else */
/*  ... other code here ... */
// Invoke some method on some other pre-existing global reference that uses
// myObjGlobalRef,  lets assume this method stores the object referenced by
// myObjGlobalRef into a parent object referenced by otherExistingGlobalRef:
env->CallVoidMethod(env, otherExistingGlobalRef, addASubObjectMethodId, myObjGlobalRef);

DeleteMyObj();

// Does the pointed to by myObjGlobalRef still exist here, assuming that
// otherExistingGlobalRef now references it?

How does this work in JNI? Is a "GlobalReference" on an object just a reference count to the object, so that if I free the GlobalReference jobject, it does not necessarily garbage collect the underlying java object until all references to it (such as the "parent" object otherExistingGlobalRef referencing it) are gone?

If you can answer this and provide a link to some official Java/Sun/Oracle documentation backing up your answer, you earn bonus kudos :-).

like image 391
Ogre Psalm33 Avatar asked Dec 02 '10 16:12

Ogre Psalm33


1 Answers

DeleteGlobalRef() frees the reference, not the object.

If that was the last reachable reference, then the referenced object is available for garbage collection.

Is a "GlobalReference" on an object just a reference count to the object

No. It's just a reference that remains valid until you free it explicitly. Java's garbage collection does not rely on reference counts at all.

See also Oracle's documentation on global references.

like image 139
Andy Thomas Avatar answered Oct 15 '22 09:10

Andy Thomas