Page 2 of 5
MyUtils.classMethod(); //first call to a static class method Vector v = new Vector(); //first call to operator new
Lazy class loading is an important feature of the Java runtime environment as it can reduce memory usage under certain circumstances. For example, if a part of a program never is executed during a session, classes referenced only in that part of the program never will be loaded.
Lazy object creation is tightly coupled to lazy class loading. The first time you use the new keyword on a class type that previously hasn't been loaded, the Java runtime will load it for you. Lazy object creation can reduce memory usage to a much greater extent than lazy class loading.
To introduce the concept of lazy object creation, let's take a look at a simple code example where a Frame uses a MessageBox to display error messages:
public class MyFrame extends Frame
{
private MessageBox mb_ = new MessageBox();
//private helper used by this class
private void showMessage(String message)
{
//set the message text
mb_.setMessage( message );
mb_.pack();
mb_.show();
}
}
In the above example, when an instance of MyFrame is created, the MessageBox instance mb_ is also created. The same rules apply recursively. So any instance variables initialized or assigned in class
MessageBox's constructor also are allocated off the heap and so on. If the instance of MyFrame isn't used to display an error message within a session, we're wasting memory unnecessarily.
In this rather simple example, we aren't really going to gain too much. But if you consider a more complex class, which uses many other classes, which in turn use and instantiate more objects recursively, the potential memory usage is more apparent.
The lazy approach to the above example is listed below, where the object mb_ is instantiated on the first call to showMessage(). (That is, not until it's actually needed by the program.)
public final class MyFrame extends Frame
{
private MessageBox mb_ ; //null, implicit
//private helper used by this class
private void showMessage(String message)
{
if(mb_==null)//first call to this method
mb_=new MessageBox();
//set the message text
mb_.setMessage( message );
mb_.pack();
mb_.show();
}
}
If you take a closer look at showMessage(), you'll see that we first determine whether the instance variable mb_ is equal to null. As we haven't initialized mb_ at
its point of declaration, the Java runtime has taken care of this for us. Thus, we can safely proceed by creating the MessageBox instance. All future calls to showMessage() will find that mb_ is not equal to null, therefore skipping the creation of the object and using the existing instance.
Let's now examine a more realistic example, where lazy instantiation can play a key role in reducing the amount of resources used by a program.
Assume that we have been asked by a client to write a system that will let users catalog images on a filesystem and provide the facility to view either thumbnails or complete images. Our first attempt might be to write a class that loads the image in its constructor.
Double-checked lockingBy Anonymous on August 4, 2009, 5:57 pmBy now (2009!!) it should be known that this could publish (return) the instance before its non-final fields (if any) are fully initialized. I think the primary...
Reply | Read entire comment
Double-checked lockingBy Anonymous on July 19, 2009, 8:02 amNope, double check locking presented in this article is valid for all versions of Java, instance need not to be declared as "volatile". This article discusses only(!)...
Reply | Read entire comment
Double-checked lockingBy Anonymous on December 23, 2008, 12:55 amBeware using the given solution for double-checked locking, it is valid only in Java 1.5+ if 'instance' is declared as volatile and is not valid in 1.4 and earlier....
Reply | Read entire comment
View all comments