What is the Java.net equivalent of GC.KeepAlive?

.NET has a GC.KeepAlive(Object) function. Its sole purpose is to provide the lifetime of the referenced object until the code stream reaches the call.

This is usually not required unless it interacts with native code.

I have a situation where I have a graph of C ++ objects accessed through JNI, where some root objects need to be kept alive in order to keep the children alive. Root objects and child objects have mirrors on the JVM ground. However, if the root object is collected and released on the C ++ side (using the created SWIG finalizer), the child objects become invalid, as their backup C ++ object will be freed.

This can be resolved by ensuring that the local variables rooting the graph of the object have a lifetime that exceeds the last use of the child object. Therefore, I need an idiomatic function that does nothing for the object, but will not be optimized or moved (for example, taken out of the loop). This is what GC.KeepAlive(Object) does in .NET.

What is an approximate equivalent in Java?

PS: perhaps an illustrative code:

 class Parent { long ptr; void finalize() { free(ptr); } Child getChild() { return new Child(expensive_operation(ptr)); } } class Child { long ptr; void doStuff() { do_stuff(ptr); } } // BAD CODE with potential for SIGSEGV for (Parent p : getParents()) { p.getChild().doStuff(); } 

The problem is that the GC freeing the parent p will free the memory allocated for the Child, while doStuff does. It has been demonstrated that GC is in practice. Potential fix if GC.KeepAlive available:

 // BAD CODE with potential for SIGSEGV for (Parent p : getParents()) { p.getChild().doStuff(); GC.KeepAlive(p); } 

I could, for example, call toString on p, but I will not do anything with its output. I can temporarily put p into an array, but how do I know that the JVM will not drop the store? Etc.

+8
java garbage-collection finalizer jni
source share
1 answer

I think you could use JMH Blackhole for this. It was designed to ensure that this link is not resolved in tests, so it should work.

Basically, it simply compares the given object reference with the stored volatile reference and reassigns it later with a small and decreasing probability (storage is expensive, so it is minimized).

+2
source share

All Articles