JVM Class Loading过程
转自:《Java Performance》第三章
VM Class Loading
The Hotspot VM supports class loading as defined by the Java Language Specification, Third Edition, [2] the Java Virtual Machine Specification, Second Edition, [1] and as amended by the updated Java Virtual Machine Specification, Chapter 5, Loading, Linking and Initializing. [3] The HotSpot VM and Java SE class loading libraries share the responsibility for class loading. The HotSpot VM is responsible for resolving constant pool symbols, that require loading, linking, and then initializing Java classes and Java interfaces. The term class loading is used to describe the overall process of mapping a class or interface name to a class object, and the more specific terms loading, linking, and initializing for the phases of class loading as defined by the Java Virtual Machine Specification. The most common reason for class loading is during bytecode resolution, when a constant pool symbol in a Java classfile requires resolution. Java APIs such as Class.forName(), ClassLoader.loadClass(), reflection APIs, and JNI_FindClass can initiate class loading. The HotSpot VM itself can also initiate class loading.
The HotSpot VM loads core classes such as java.lang.Object and java.lang.Thread along with many others at HotSpot VM startup time. Loading a class requires loading all Java superclasses and all Java superinterfaces. And classfile verification, which is part
of the linking phase, can require loading additional classes. The loading phase is a cooperative effort between the HotSpot VM and
specific class loaders such as java.lang.ClassLoader.
Class Loading Phases
For a given Java class or Java interface, the load class phase takes its name, finds the binary in Java classfile format, defines the Java class, and creates a java.lang.Class object to represent that given Java class or Java interface. The load class phase can throw a NoClassDefFound error if a binary representation of a Java class or Java interface cannot be found. In addition, the load class phase does format checking on the syntax of the classfile, which can throw a ClassFormatError or UnsupportedClassVersionError. Before completing the load of a Java class, the HotSpot VM must load all its superclasses and superinterfaces. If the class hierarchy has a problem such that a Java class is its own superclass or superinterface (recursively), then the HotSpot VM throws a ClassCircularityError. The HotSpot VM also throws an IncompatibleClassChangeError if the direct superinterface is not an interface, or the direct superclass is an interface.The link phase first does verification, which checks the classfile semantics, checks the constant pool symbols, and does type checking. These checks can throw a VerifyError. Linking then does what is called preparation, which creates and initializes static fields to standard defaults and allocates method tables. It is worth noting at this point of execution no Java code has yet been run. The link class phase then optionally does resolution of symbolic references. Next, class initialization runs the class static initializers, and initializers for static fields. This is the first Java code that runs for this class. It is important to note that class initialization requires superclass initialization, although not superinterface initialization.
The Java Virtual Machine Specification specifies that class initialization occurs on the first active use of a class. However, the Java Language Specification allows flexibility in when the symbolic resolution step of linking occurs as long as the semantics of
the language are held; the JVM finishes each step of loading, linking, and initializing before performing the next step; and throws errors when Java programs would expect them to be thrown. As a performance optimization, the HotSpot VM generally waits until
class initialization to load and link a class. This means if class A references class B, loading class A will not necessarily cause loading of class B (unless class B is required for verification). Execution of the first instruction that references class B
causes the class initialization of B, which requires loading and linking of class B.