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.
--
- DML
More information about the core-libs-dev
mailing list