This question is provoked by this post. When a simple program like the following is run
public class Sample
{
public static void main(String[] args)
{
}
}
with options -versbose:class
, it lists a bunch of classes before loading this class
[Opened C:\jdk1.6.0_14\jre\lib\rt.jar]
[Loaded java.lang.Object from C:\jdk1.6.0_14\jre\lib\rt.jar]
[Loaded java.io.Serializable from C:\jdk1.6.0_14\jre\lib\rt.jar]
[Loaded java.lang.Comparable from C:\jdk1.6.0_14\jre\lib\rt.jar]
.
.
.
.
.
.
[Loaded java.security.cert.Certificate from C:\jdk1.6.0_14\jre\lib\rt.jar]
[Loaded Sample from file:/D:/tmp/]
[Loaded java.lang.Shutdown from C:\jdk1.6.0_14\jre\lib\rt.jar]
[Loaded java.lang.Shutdown$Lock from C:\jdk1.6.0_14\jre\lib\rt.jar]
My questions is,
my program never needed classes like java.util.Collection
, Set
List
and so on. Then why is Bootstrap classloader is loading them. Is this how JVM specs mandates or how Bootstrap classloader decides which classes to load ?
EDIT:
Another aspect:
Even if you try to run a non existent class, the program ends with ClassNotFoundException
but not without loading all the classes mentioned earlier. So the classes are loaded merely on invoking the JVM ! So JVM loads a set of classes by default but, what governs this behavior?
Class
is the part of java.lang
package and so the bootstrap class loader picks it up for loading, but Class
itself requires some dependent framework classes like List
or Set
, so they are also loaded.
If you will see the code for Class
in JDK you will find following imports
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.LinkedList;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.Map;
import java.util.HashMap;
Class
source internally uses Collections
, so it needs to be loaded.
There seems to be some misunderstanding what the bootstrap classloader is:
VM's built-in classloader
java.
classes, i.e. classes starting with java. cannot be loaded by anything else (this is part of the security model)object.getClass().getClassLoader()
returns null
as usually the bootstrap classloader is in the native/C code (part of the JVM), i.e. it's not a java class (as it cannot be loaded by itself, see chicken/egg above)Now to answer the direct question: "what governs this behavior?" - When the first time an attempt is made to load a class via 'Class.forName', normally the current class' classloader asks its own parent to do so. Bootstrap classloader is considered parent of the system classloader (that loads the main class). If the current class has been already loaded by the bootstrap classloader it uses the VM to resole the class needed loading.
Last - classes in java are always loaded dynamically when they are needed, every time there is an attempt to invoke a method - it takes a fully qualified classname from the constant pool that has to be resolved. That behavior is independent from the class' classloader. So when the very 1st class is materialized by the JVM, the ball starts rolling.
JRE probably does lazy loading, i.e. a class is loaded only when it's needed.
However, before your main class is accessed, JRE is already executing a lot of other java codes, notably, sun.misc.Launcher
. That's why a lot of classes are loaded before your class.
Generally speaking, it's within JRE's discretion to load whatever classes it likes to, whenever.
http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.1.2
An implementation may resolve symbolic references from a class or interface that is being linked very early, even to the point of resolving all symbolic references from the classes and interfaces that are further referenced, recursively.
An implementation may instead choose to resolve a symbolic reference only when it is actively used; consistent use of this strategy for all symbolic references would represent the "laziest" form of resolution.
Note that initialization of classes happens at strictly specified moments; there's no "eager" initialization -- http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With