When a class A
is being loaded, assume the byte code of A
has references to many other classes. Let us say class A
looks like below.
class A extends B implements C,D {
static E e;
F f;
A() {
G g = new G();
}
void print(H h) {
}
}
Does JVM load all the classes that are used by A
? Or It does not bother about them until the class is initialised?
If at least some of them are loaded, will they be loaded after A
completes? or A's
loading will pause till the required class loads?
For this question, assume none of the other classes are loaded yet. Even super class B
and Interfaces C
& D
.
To understand this, let understand some basics for this. This will help any novice person to understand lazy loading in JAVA.
If you're familiar with Netscape's Web browser and have used both versions 3.x and 4.x, undoubtedly you've noticed a difference in how the Java runtime is loaded. If you look at the splash screen when Netscape 3 starts up, you'll note that it loads various resources, including Java. However, when you start up Netscape 4.x, it doesn't load the Java runtime -- it waits until you visit a Web page that includes the tag. These two approaches illustrate the techniques of eager instantiation (load it in case it's needed) and lazy instantiation (wait until it's requested before you load it, as it may never be needed).
There are drawbacks to both approaches: On one hand, always loading a resource potentially wastes precious memory if the resource isn't used during that session; on the other hand, if it hasn't been loaded, you pay the price in terms of loading time when the resource is first required.
Consider lazy instantiation as a resource conservation policy
Lazy instantiation in Java falls into two categories:
Lazy class loading
The Java runtime has built-in lazy instantiation for classes. Classes load into memory only when they're first referenced. (They also may be loaded from a Web server via HTTP first.)
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
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.
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.
Conclusion: It will load all dependent object as soon as those are initliazed with child entities.To reduce the memory footprint we should carefull look for these kind on design patterns like , Virtual Proxy, Lazy initialization