Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java direct memory: using sun.misc.Cleaner in custom classes

Tags:

java

In Java the memory allocated by NIO direct buffers is freed with sun.misc.Cleaner instances, some special phantom references that are more efficient than object finalization.

Is this cleaner mechanism hardcoded in the JVM only for the direct buffer subclasses, or is it possible to also use cleaners in custom components (writing a custom direct byte buffer for instance)?

Here I am not talking about retrieving the cleaner field of an existing nio direct buffer. I am not talking either about manually freeing the memory. This is about writing a new class that allocates direct memory and has it cleaned efficiently and automatically by the garbage collector mechanism.

like image 275
Antoine CHAMBILLE Avatar asked Jul 16 '13 07:07

Antoine CHAMBILLE


2 Answers

After spending more time reading the API doc ( http://docs.oracle.com/javase/7/docs/api/java/lang/ref/package-summary.html ) I think I have a more detailed answer:

1) it is possible to reuse sun.misc.Cleaner to perform the efficient cleanup of your own custom classes. You declare the cleaner by calling the provided factory method:

sun.misc.Cleaner.create(Object ob, Runnable cleanup);

For some time I could not get it to work properly, that's because I was moronic enough to define the runnable cleanup code of my cleaner as an anonymous class, that kept a (strong) reference to my referent object, preventing it from ever being "phantom reachable"...

2) There is no other way to implement such efficient cleanup (not even with the help of phantom references)

Indeed the reference handler thread handles instances of sun.misc.Cleaner in a special way:

// Fast path for cleaners
if (r instanceof Cleaner) {
    ((Cleaner)r).clean();
    continue;
}

That means that the cleanup code is called directly from the reference handler thread, while in standard usage, the references must be enqueued by the reference handler thread and then dequeued and processed by another application thread.

like image 167
Antoine CHAMBILLE Avatar answered Oct 16 '22 06:10

Antoine CHAMBILLE


If you rely on anything in a sun.misc package, you run the risk of it disappearing and breaking your code. Some pieces are more stable than others, but it's often a bad idea (devil's advocate: a lot of the methods in sun.misc.Unsafe are actually implemented by JVM intrinsics, making them faster than user-written JNI code).

In this case, I think it's a bad idea: Cleaner is one possible implementation of cleanup via PhantomReference. There are others; Google for examples. For that matter, you could look at the source code of Cleaner itself as an example of how to use phantom references.

You will need some sort of cleanup handler if you're going to have on-heap objects that refer to off-heap objects. Otherwise you'll create a true memory leak when those on-heap objects get collected.

like image 31
parsifal Avatar answered Oct 16 '22 05:10

parsifal