Hi Andrew,
On Wed, Sep 3, 2014 at 12:58 PM, Andrew Haley <a...@redhat.com> wrote: > On 03/09/14 01:15, Stanimir Simeonoff wrote: > > > Like David Lloyd mentioned finalize() can be invoked concurrently to > > some methods (if there is no reachability to 'this'). OTOH I see > > finalize useful for managing native resources mostly and possibly > > stopping (signaling) threads left unmanaged. In that particular case > > synchronization is a must, so it comes naturally. > > But finalize isn't useful for managing native resources because > finalizers may or may not run, as you note. People will test their > programs with one implementation then discover, when their programs > are deployed, that they sometimes mysteriously fail. In particular, > you might run out of file handles. > > 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. The direct/mapped buffers are ones that don't have proper lifecycle, esp. the mapped ones The latter don't offer munmap. I believe the java.nio.Bits still includes a notorious call in a static void reserveMemory(long size, int cap) { //check if above the direct memory threashold and... System.gc(); try { Thread.sleep(100); } catch (InterruptedException x) { // Restore interrupt status Thread.currentThread().interrupt(); } } in an attempt to cope with the lack of proper and timely finalization. Prior the fix the OOM when using DirectBuffers was quite guaranteed unless pooling the buffers on your own. On a flip note, I think it's kind of a bug as it has to manually call run System.runFinalization() prior throwing the OOM, but it opts to sleep 100ms instead. If the finalizers don't run prior the process termination, that's ok as the OS should be able to clean up any native resources allocated on its own. However finalizers not running is not that different from a weak/phantom reference not being enqueued, practically the odds are quite the same. The impl. of the finalization is actually a high priority dedicated thread that processes a ReferenceQueue. > As Jarolsav put it, "I don't think this is explainable to regular Java > developers." As David Lloyd put it, "If you still think that finalize > is a good idea, given that it's basically defective *and* there is > almost always a better solution, then I will be quite astounded." As > I put it, "finalize is broken." > > I'd not say "broken", as it works exactly as specified. Still I utterly agree it requires pretty deep knowledge on the inner works to make it somewhat useful. Stanimir