Why is finalize wrong?

David M. Lloyd david.lloyd at redhat.com
Wed Sep 3 12:56:27 UTC 2014

On 09/03/2014 06:48 AM, Stanimir Simeonoff wrote:
> Hi Andrew,
> On Wed, Sep 3, 2014 at 12:58 PM, Andrew Haley <aph at 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.

This is why everyone pools buffers.  The following code:

> 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();
>          }
> }

is basically crap, and the first thing any serious NIO developer will do 
is defeat it with buffer pooling.


More information about the core-libs-dev mailing list