Why is finalize wrong?
stanimir at riflexo.com
Wed Sep 3 14:13:57 UTC 2014
>>> I meant cleaning up rather than managing per se. To make it clear:
>> finalization is no substitute for proper lifecycle - anything that has
>> open() should have a following up close(), otherwise it's a bug.
>> Finalization still helps as safenet vs leaving native resources totally
>> unallocated and leaking. Yet, finalizers have to run somehow since the
>> direct (and mapped) buffers very heavily rely on them.
> DirectByteBuffers rely on Cleaner(s), which are PhanthomReferences and are
> managed (invoked) by the ReferenceHandler thread directly. Finalizers are
> just enqueued by ReferenceHandler thread, but they are invoked by the
> special FinalizerThread. That's because Cleaner(s) are internal JDK
> mechanism, while finalizers invoke client code so they can stall the
> FinalizerThread. A bug in a client code can bring FinalizerThread to a halt.
Cleansers totally slipped my mind regarding DirectBuffers(almost feel
ashamed about). Yes, all the nio is using them.unlike
java.io.FIleInputStream, java.util.zip.Deflater/Inflater. I remember a
process getting justice by the oom_killer b/c a Deflater was not end()'d
properly. I am not sure if Deflater (which a memory hog) could use Cleaner,
Again halting the Finalizer is a slow leak. The memory will fill with tons
of java.lang.ref.Finalizer instances, so either way it'd be OOM, just takes
more time and blows up unexpectedly.
As said, DirectByteBuffer(s) use Cleaner(s), which are more predictable.
> But even with Cleaner(s), a multithreaded test could be constructed which
> reserves direct memory with greater rate than single ReferenceHandler
> thread can unreserve it. Until this was fixed:
> Thanks again for the Cleaner reminder.
Pooling doesn't help 32bit processes running out of address space due to
lack of munmap. FileChannelImpl employs the same tactic to call System.gc()
More information about the core-libs-dev