B.Tech in Computer Science and Enginering, interested in Distributed Systems. Currently working as a Software Development Engineer in Amazon Swaranga is a DZone MVB and is not an employee of DZone and has posted 4 posts at DZone. You can read more from them at their website. View Full User Profile

Garbage Collection with Automatic Resource Management in Java 7

03.30.2012
| 6193 views |
  • submit to reddit

This post provides a brief overview of a new feature introduced in Java 7 called Automatic Resource Management or ARM. The post delves how ARM tries to reduce the code that a developer has to write to efficiently free the JVM heap of allocated resources.

One of the sweetest spots of programming in the Java programming language is automatic handling of object de-allocation. In Java world this is more popularly known as garbage collection; it basically means that developers do not have to worry about de-allocating the object allocated by their code. As soon as a developer is finished with using the object he can nullify all references to the object and then the object becomes eligible for garbage collection.

Garbage collection has a flip side to it however. Unlike in C/C++ where the coder has complete control of memory allocation and de-allocation [malloc, free, new, delete etc], in Java the developer does not have significant control over the process of de-allocation of objects. The JVM manages the process of garbage collecting of unused objects and it is really up to the whims of the JVM when to run a cycle of garbage collection. True, there are method calls like System.gc() or Runtime.getRuntime().gc() that indicates that garbage collection will be run, but these methods merely serve to remind the JVM that -"maybe you need to run a garbage collection now, just a suggestion, no pressure!". The JVM is fully authorized to disregard such requests and is coded to run garbage collection only when it really sees fit. Hence in practice, developers are always advised not to build their program logic believing System.gc() or Runtime.getRuntime().gc() will trigger a full garbage collection.

There is no denying how much good automatic garbage collection has done to enhance the productivity of developers. However there are some corner cases where garbage collection is not sufficient to mantain a "clean" heap, free of unused objects. Especially if the objects deal with some form of native resources that is served by the underlying operating system. These objects include, but are not limited to IO streams, database connections etc. For these kind of objects developers must release the resources explicitly. Typically these are done through try-catch blocks.

Let us look at a small example that closes an InputStream after finishing the processing of the stream:

InputStream in = null;

try
{
    in = new FileInputStream(new File("test.txt");
    //do stuff with in
}
catch(IOException ie)
{
    //SOPs
}
finally
{
    //do cleanup
}
The above looks good and clean; however as soon as we try to close the input stream via in.close() in the finally block, we need to surround it with a try-catch block that catches the checked exception, IOException. Thus the code sample transforms to:
InputStream in = null;

try
{
    in = new FileInputStream(new File("test.txt"));
    //do stuff with in
}
catch(IOException ie)
{
    //SOPs
}
finally
{
    try
    {
        in.close();
    }
    catch(IOException ioe)
    {
        //can't do anything about it
    }
}

Now the above code looks bloated, and with multiple kinds of checked exceptions in different hierarchy, we need more catch clauses. Very soon the code becomes lengthy and difficult to maintain, not to mention the code losing its initial clean and no-nonsense look that even appealed to the eye.

But there is a good news.

Java 7 makes this easier with the new try-catch block. With this feature we can avoid the finally block itself. This is how we do it:

try(InputStream in = new FileInputStream(new File("test.txt"))
{
    //do stuff with in
}
catch(IOException ie)
{
    //SOPs
}

The above block of code will do the cleanup part itself. This is made possible by the introduction of a new interface, java.lang.AutoCloseable which defines a single method, void close() throws Exception. Objects which are subtypes of this interface can be automatically close()d using the above syntax. The above feature is applicable to objects of any class that implement the AutoCloseable interface.

The best part is that even if we initialize multiple AutoCloseable instances in the try() block, it will call the close() method for all the objects, even if some close() method on some object throw any exception.

Coming to the handling of the exceptions, if there was any IOExceptions in our try block as well as in the implicit finally block [where the AutoCloseables are actually being close()ed], the exception thrown will be the one that was thrown in the try block rather than the one in the implicit finally block.

However we can still have the details of the implicit finally block's exception from the method Throwable.getSuppressed() which is added as a new method in Java 7

I think Automatic Resource Management feature, or ARM is a great addition to Java 7.

 
Published at DZone with permission of Swaranga Sarma, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Jilles Van Gurp replied on Sat, 2012/03/31 - 3:38am

Eh, resource management has very little, if anything, to do with garbage collection. Memory is not a resource that you close. Instead resource management is about managing system resources like file handles (which are used for both network connections and files) and making sure you don't run out of those.

The reason you shouldn't do manual garbage collection is that you need to tune the garbage collector to do the right thing rather than making assumptions about how it works and how it is configured and then trying to blow your feet off by triggering full garbage collects (expensive) all the time.

So, implementing an AutoClosable that actually triggers garbage collection (which I hope you were not suggesting) would be a pretty bad idea.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.