Proposal: Automatic Resource Management

Reinier Zwitserloot reinier at zwitserloot.com
Mon Mar 1 12:47:11 PST 2010


This won't work very well.

We already _HAVE_ finalize(), and could be used for this. The reason
finalize() isn't used for ARM is because the concept of finalization is
extremely complicated. Basically, objects may live for hours after they
become eligible for finalization; if not much in the JVM is requiring new
heap memory then gc may not happen for a long time. However, keeping OS
resources (such as files and sockets, or DB connectors) open has a
significant cost associated with it, *and* close often finalizes a
transaction of some sort (e.g. a close() on a file will flush any buffers,
on a zip stream it'll write the zip descriptor, it'll send the close
connection packets for TCP/IP sockets, and it'll commit or rollback an open
transaction for a DB connector). It is therefore important that the point at
which a resource is closed is carefully managed and happens at a very
precise moment. Not 'sometime later. Possibly hours later'.

Perhaps you meant that an AutoClosable/Disposable object should get its
autoClose()/dispose() method called *IMMEDIATELY* when it becomes eligible
for garbage collection. However, that's not how the JVM works. It does
*not*, after every instruction, check if some object reference has now
become eligible and mark it for the next sweep of the GC to clean it up. So,
if this was your idea, then it is not practically implementable - at least,
there is no obvious way to do it, and you haven't given us any idea about
how to go about updating the JVM to make this possible.

Lastly, such a change is JVM based and such changes are usually too tricky
and have too much impact to fit within the mission of Project Coin.

--Reinier Zwitserloot



On Mon, Mar 1, 2010 at 11:15 AM, Mohamed M. El-Beltagy <melbeltagy at yahoo.com
> wrote:

> I've read as much as I can of the ARM proposal and related emails. I'm not
> sure that I read it all, I tried to read all.
> >From what I read and what I have in mind, I think I might be rolling back
> some ideas that kept on going in the different discussions. So, please, bare
> with me.
>
> The proposal I have is a little combined of what you have suggested, but
> changed a little bit and yet, I tried to make it, simple.
> We would have two special interfaces similar to the Serializable interface.
> The two interfaces would be in any package (no need for special package).
> The interfaces would be, as suggested, AutoClosable and AutoDisposable. But
> with the following implementations:
> public interface AutoClosable {
>    public void autoClose() throws Exception;
> }
>
> public interface AutoDisposable{
>    public void autoDispose() throws Exception;
> }
>
> and the platform would pay attention to the marker interfaces and call the
> appropriate method.
>
> It would be the responsibility of the implementing classes to implement the
> method with internal call to the original close method.
> For example:
> Implementation of a FileWriter is:
> public class FileWriter implements AutoXXXX {
>    public void autoXXXX() throws Exception {
>        close();
>    }
>    // existing class code
> }
>
> In regards to the scope of the ARM and declaration of the resource to be
> managed, it would be the same as the variable scope that references the
> object. i.e, whenever the object is eligible for garbage collector, it would
> auto close or dispose the object before collecting it. (same as finalize
> method).
> Or as another suggestion to the matter, the compiler would be responsible
> for deciding when to insert the call of the autoXXXX method in the generated
> classes. (but I guess this solution would not be fully backward compatible
> with previously compiled classes on new JRE).
>
> In regards to whether or not an implementing class can implement two
> interfaces, we could have two options:
> Option 1:
>       It would be the responsibility of the implementing class to secure
> the internal state of itself. Meaning: it would check if it's already closed
> or disposed or not before invoking the original close/dispose method.
> Advantage: the user of the class could have successfully closed the object
> before it's auto closed using the existing way of closing connections and
> files. So, no need to auto close it as it is already closed. Disadvantage:
> things will be, again, implementation specific which gives the developer the
> chance of miss handling the resource's state.
>
> Option 2:
>       The compiler would give a higher priority to one of the two marker
> interfaces. Disadvantage: implementation still needs to handle the internal
> state of the itself (is it closed already or not).
>
>
> Overall benefits:
>    1. No language changes are required at all. With this proposal, we could
> even apply it to Java SE prior to Java 5, if we would like to.
>    2. Fully backward compatibility.
>    3. It overcomes the shortcoming of the updated proposal (
> http://docs.google.com/Doc?id=ddv8ts74_0vnstdfdh) that the implementation
> class can decide which exception to be thrown out of the
> autoClose/autoDispose and which to be ignored.
>    4. It eliminates the need for special handling in for-loop as it could
> be applied to any class (normal resources like streams, or any special
> collection that needs to be closed or disposed). The for-loop has nothing to
> do with close/dispose of an object. It's purpose is for iteration. So we
> would not mix the responsibilities of the code and thus, the code is doing
> what it's intended to do as well as keeping backward compatibility with
> existing code.
>        One of the cases I read in the discussions was what if there is a
> collection of disposable items. In this case, when the scope of the
> collection is over, the items contained inside are over, and thus, eligible
> for closing/disposal. So, again, the runtime would be able to call the
> autoClose/autoDispose methods.
>    5. No need for new language keywords.
>    6. No usage of annotations.
>    7. The existing resources implementations could be added gradually to
> the list of supported resources by the ARM, they don't have to be all
> released in Java 7.0. Only support for ARM with the new two interfaces is
> required. i.e., changing class FileWriter  in the API to support ARM does
> not have to be in Java 7.0, it could be added later in a minor update.
>    8. One of the things I really find interesting, is that we can even
> start with one special interface to the ARM feature (AutoClosable, to be
> specific) and we can add other special interfaces later on as required
> (AutoDisposable, AutoOpenable, etc.). This way, the ARM feature itself would
> be expandable and yet controllable by the platform).
>
> Disadvantages:
>    1. For each implementing class, we will need to change the current
> implementation to add the following:
>        a) Add the implements AutoXXXX declaration.
>        b) Implement the new method autoXXXX.
>        c) Check the internal state of the class before closing. (the most
> annoying thing).
>    2. I really have no clue about the amount of work required in the
> compiler/run-time to support this feature. But if we are considering ARM in
> all cases, I guess this would be the minimal changes required.
>
> I really hope that you find my contribution in the ARM topic worth it and I
> certainly hope that I didn't waste anyone's time.
>
>
>
>
>



More information about the coin-dev mailing list