0

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.

subject-q
  • 91
  • 3
  • 19
  • *or A's loading will pause till the required class loads?* - of course, first all the dependencies needs to be loaded, then the class that needs them. and it seems you ask if classes are lazy-loaded, then the answer is yes – Eugene Apr 03 '19 at 09:55
  • @Thilo so when `A` is being loaded, `B`, `C`, `D`, `E`, `F`, `H` are loaded. `G` is loaded when an instance of `A` is instantiated? Basically that means: super classes, interfaces and any classes that is in type/method signature of any member are loaded when the containing class is loaded. But the ones present in execution code (classes that are not yet loaded) are loaded when they are faced the first time? – subject-q Apr 03 '19 at 10:05
  • @Thilo why would `H` be loaded if that method is not called? – Eugene Apr 03 '19 at 10:07
  • Not at all, you don't need information about the types that appear in the signatures when you're not calling the methods, and you don't need information about the field types when you're not accessing them. You also don't need information about the interfaces you're implementing unless they provide default methods you don't. So, when you load A and don't do anything with it, it only loads B before, and possibly C and D if they provide default methods. – kumesana Apr 03 '19 at 10:08
  • @kumesana very interesting point about the `default` methods... do you happen to know the JLS reference for that? – Eugene Apr 03 '19 at 10:12
  • @Eugene https://docs.oracle.com/javase/specs/jls/se12/html/jls-12.html#jls-12.4.2 step 7 – kumesana Apr 03 '19 at 10:20
  • @Thilo fundamentally, you could try – kumesana Apr 03 '19 at 10:23
  • @Thilo exactly, as stated. I did try... and it's not the case – Eugene Apr 03 '19 at 10:23
  • @kumesana thank you for the link, this explains so much with a production fix I had to put in. much appreciated. – Eugene Apr 03 '19 at 10:27
  • @kumesana do I take that super classes is required to be loaded when subclass is being loaded. And also the interfaces that sub class implements if they contain default methods? – subject-q Apr 03 '19 at 10:36
  • 1
    @ArunRajagopal yes. Basically to load a class you need to be able to bind its methods. – kumesana Apr 03 '19 at 11:40
  • 1
    I suggest reading [this answer](https://stackoverflow.com/a/34263422/2711488) and [this one](https://stackoverflow.com/a/39268133/2711488). If you still have more time and patience, here’s [another one](https://stackoverflow.com/a/52703533/2711488) hopefully helpful. – Holger Apr 03 '19 at 11:52
  • @kumesana if binding methods is needed then won't `H` also need to be loaded along with other classes's return type or argument classes? – subject-q Apr 03 '19 at 12:54
  • 1
    Nah. All we need to know is that it is called H. Whatever it is made of is irrelevant. – kumesana Apr 03 '19 at 12:56

1 Answers1

2

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
  • List item

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

Sohan
  • 6,252
  • 5
  • 35
  • 56
  • are you saying not only when `MyFrame` is loaded or initialised, `MessageBox` class is not loaded till the jvm executes the line `mb_ = new MessageBox();`? Also when would `Frame` be loaded? – subject-q Apr 03 '19 at 10:28
  • I'm saying that even if you initialize the MyFrame class, the MessageBox is not initialized or loaded into heap by JVM. We have taken care of that in code and JVM takes care as well. As you initialize the MyFrame, JVM will load first it's dependent classes (refrences) – Sohan Apr 03 '19 at 10:33
  • My question is more about, when `MyFrame` class is loaded into JVM does the loading mechanism pause and load `MessageBox` into JVM first? I may have it misunderstood. Does initialisation and loading happen hand in hand? – subject-q Apr 03 '19 at 10:35
  • Yes, unless you give a call to that method in above example. – Sohan Apr 03 '19 at 10:48