Dissecting the Java Virtual Machine - Architecture - part 2

   Lets get back to the basic archictural diagram and see what happens in little more detail:

hotspot architecture diagram 1

   Class files are loaded from a particular resource - the file system, JAR archives, over the network etc. For that reason the class loader subsystem is being used. As most you already know there are three standard
classloaders used by the JVM:

   - the bootstrap classloader that loads the core Java libraries located in the <JAVA_HOME>/jre/lib. It is implemented in <OpenJDK_root>/jdk/src/share/native/java/lang/ClassLoader.c;

   - the extensions class loader that loads classes from the JVM extension directories (<JAVA_HOME>/jre/lib/ext or any other directory specified by the java.ext.dirs system property). It is implemented in <OpenJDK_root>/jdk/src/share/classes/sun/misc/Launcher.java
(sun.misc.Launcher$ExtClassLoader);

   - the system class loader that loads code found on java.class.path, which maps to the CLASSPATH environment variable. It is implemented in <OpenJDK_root>/jdk/src/share/classes/sun/misc/Launcher.java (sun.misc.Launcher$AppClassLoader)

   The structure of a class file is desribed by the following diagram:

classfile structure

   The fields are:

   - magic - The magic item supplies the magic number identifying the class file format; it has the value 0xCAFEBABE;

   - minor_version, major_version - the values of the minor_version and major_version items are the minor and major version numbers of this class file;

   - constant_pool_count - the value of the constant_pool_count item is equal to the number of entries in the constant_pool table plus one;

   - constant_pool[] - the constant_pool is a table of structures representing various string constants, class and interface names, field names, and other constants that are referred to within the ClassFile structure and its substructures. access_flags. The value of the access_flags item is a mask of flags used to denote access permissions to and properties of this class or interface;

   - this_class - The value of the this_class item must be a valid index into the
constant_pool table;

   - super_class - for a class, the value of the super_class item either must be zero or must be a valid index into the constant_pool table;

   - interfaces_count - the value of the interfaces_count item gives the number of direct superinterfaces of this class or interface type;

   - interfaces[] - each value in the interfaces array must be a valid index into
the constant_pool table;

   - fields_count - the value of the fields_count item gives the number of field_info structures in the fields table. The field_info structures represent all
fields, both class variables and instance variables, declared by this class or
interface type;

   - fields[] - each value in the fields table must be a field_info structure giving
a complete description of a field in this class or interface;

   - methods_count - the value of the methods_count item gives the number of method_info structures in the methods table;

   - methods[] - each value in the methods table must be a method_info structure giving a complete description of a method in this class or interface;

   - attributes_count - the value of the attributes_count item gives the number of attributes in the attributes table of this class;

   - attributes[] - each value of the attributes table must be an attribute_info structure.

So during classloading we have three separate phases:
   - loading: finding and importing the binary data for a type;
   - linking: performing verification, preparation, and (optionally) resolution;
   - verification: ensuring the correctness of the imported type; there are three subphases of of the verification phase;
      - preparation: memory for class variables is allocated and initialized to default values;
      - resolution: transforming symbolic references from the type into direct references;
      - initialization: Java code is invoked that initializes class variables to their proper starting values.

   During classloading you should differentiate between class format checking (that checks for the validity of the class file structure during the loading phase) and the bytecode verification phase - that verifies that the bytecode does not have important violations (such as uninitialized variables, method calls that do not match the type of object references, violations of rules regarding data access rules, local variable access violations or stack overflow). 

Share