On 09/03/2014 06:48 AM, Stanimir Simeonoff wrote:
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.
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