I noticed that ResultSet
implements the AutoCloseable
interface in the Java 3.0 release, adding the close()
method. Usage in test code uses this with try-with-resources to call close()
automatically. But I don’t see any reference to this pattern or calling close()
in the docs.
Is this just an optimization, or a preferred pattern? It seems the underlying c4enum.close()
is eventually called in finalize()
. Is the intent for this to free the underlying native resource more eagerly, rather than waiting on garbage collection?
Also, am I correct that there’s no need for a similar close()
in the ObjC SDK, since memory is freed eagerly via reference counting?
tl;dr: yes, exactly.
I am trying to move any object whose recursive closure dominates a C object, to be AutoClosable. I intend this to be a marker for client coders that these objects should be closed, explicitly, when possible. It is, clearly, not always reasonable or even possible to do that.
Any AutoClosable object also has a finalizer that frees its native companion object. Depending on a finalizer, though, has the problem that, with a larger memory space, you can build up a ton of unreachable objects that only get dumped on the finalizer thread when a major GC happens. Suddenly a single thread is stuck freeing hundreds of objects, some of which may take significant portions of a second, to free. This can lead to unnecessary OOMs.
You are sort of correct about iOS not having a need for something similar. Even in Java, though, the C companion objects are always freed by eager reference counting. The problem in Java is that the Java object must retain (increase the ref count of) the C object until it is no longer useful. That’s either close
or finalize
Thanks for the explanation. I wonder if this memory management optimization might have an affect on the the high memory usage I was finding in these benchmarks a while back. I might try revisiting that code to see if it’s changed at all in the last couple years.