Program Execution happens in the following steps in Sequence
- Load ( Using a ClassLoader)
- Link
- Verify - Symbol Table, Semantically correct.
- Prepare - Static storage , Method Table.
- Resolve - ( Optional ) - Reference to other Classes/Interfaces.
- Initialize - Class Variable Initializers, Static Initializers, In textual order. If a class has a Super class then that needs to be initialised first, which first requires Loading & Linking (Verifying,Preparing & Resolving)
- Unload
- Exit
Loading
Loading is the process of Finding the binary form of a class with a particular name and constructing a Class object to represent the class. The method defineClass of class ClassLoader may be used to construct Class objects from binary representations in the class file format.
LinkageError has subclasses ClassCircularityError, ClassFormatError, NoClassDefFoundError, OutOfMemoryError.
A Classloader hierarchy is maintained.
Bootstrap is the top classloader. Any classloading is first delegated to Parent till it reaches Bootstrap classloader. If parent cant load it is delegated back to the child.
- Class objects for array classes are not created by class loaders, but are created automatically as required by the Java runtime.
- The class loader for an array class, as returned by Class.getClassLoader() is the same as the class loader for its element type; if the element type is a primitive type, then the array class has no class loader.
- Each instance of ClassLoader has an associated parent class loader The virtual machine's built-in class loader, called the "bootstrap class loader", does not itself have a parent but may serve as the parent of a ClassLoader instance
- Security Checks in the Class Loader
- While a Java program is executing, it may in its turn request that a particular class or set of classes be loaded, possibly from across the network.
- After incoming code has been vetted and determined clean by the bytecode verifier, the next line of defense is the Java bytecode loader. The environment seen by a thread of execution running Java bytecodes can be visualized as a set of classes partitioned into separate name spaces.
- There is one name space for classes that come from the local file system, and a separate name space for each network source. When a class is imported from across the network it is placed into the private name space associated with its origin.
- When a class references another class, it is first looked for in the name space for the local system (built-in classes), then in the name space of the referencing class.
- There is no way that an imported class can "spoof" a built-in class. Built-in classes can never accidentally reference classes in imported name spaces--they can only reference such classes explicitly. Similarly, classes imported from different places are separated from each other.
Linking
Linking is the process of taking a binary form of a class or interface type and combining it into the runtime state of the Java virtual machine, so that it can be executed.
Verification - Verification ensures that the binary representation of a class or interface is structurally correct. it checks that every instruction has a valid operation code; that every branch instruction branches to the start of some other instruction, rather than into the middle of an instruction; that every method is provided with a structurally correct signature; and that every instruction obeys the type discipline of the Java virtual machine language.
If an error occurs during verification, then an instance of the following subclass of class LinkageError will be thrown - VerifyError
The tests range from simple verification that the format of a code fragment is correct, to passing each code fragment through a simple theorem prover to establish that it plays by the rules:
it doesn't forge pointers,
it doesn't violate access restrictions,
it accesses objects as what they are (for example, InputStream objects are always used as InputStreams and never as anything else).
Once the verifier is done, a number of important properties are known:
There are no operand stack overflows or underflows
The types of the parameters of all bytecode instructions are known to always be correct
Object field accesses are known to be legal--private, public, or protected
If an error occurs during verification, then an instance of the following subclass of class LinkageError will be thrown - VerifyError
The tests range from simple verification that the format of a code fragment is correct, to passing each code fragment through a simple theorem prover to establish that it plays by the rules:
it doesn't forge pointers,
it doesn't violate access restrictions,
it accesses objects as what they are (for example, InputStream objects are always used as InputStreams and never as anything else).
Once the verifier is done, a number of important properties are known:
There are no operand stack overflows or underflows
The types of the parameters of all bytecode instructions are known to always be correct
Object field accesses are known to be legal--private, public, or protected
Preparation - Preparation involves creating the static fields (class variables and constants) for a class or interface and initializing such fields to the default values. This does not require the execution of any source code; explicit initializers for static fields are executed as part of initialization , not preparation.
Resolution - (is Optional can be done at Runtime). Before a symbolic reference can be used it must undergo resolution, wherein a symbolic reference is checked to be correct and, typically, replaced with a direct reference that can be more efficiently processed if the reference is used repeatedly. IncompatibleClassChangeError, IllegalAccessError, InstantiationError, NoSuchFieldError, NoSuchMethodError, UnsatisfiedLinkError
Initialization
Initialization of a class consists of executing its static initializers and the initializers for static fields (class variables) declared in the class. Initialization of an interface consists of executing the initializers for fields (constants) declared there. Before a class is initialized, its superclass must be initialized, but interfaces implemented by the class are not initialized. Similarly, the superinterfaces of an interface are not initialized before the interface is initialized.
Initialization of a class consists of executing its static initializers and the initializers for static fields (class variables) declared in the class. Initialization of an interface consists of executing the initializers for fields (constants) declared there. Before a class is initialized, its superclass must be initialized, but interfaces implemented by the class are not initialized. Similarly, the superinterfaces of an interface are not initialized before the interface is initialized.
Invocation of certain reflective methods in class Class and in package java.lang.reflect also causes class or interface initialization. A class or interface will not be initialized under any other circumstance
A reference to a class field causes initialization of only the class or interface that actually declares it, even though it might be referred to through the name of a subclass, a subinterface, or a class that implements an interface.
final class variables and fields of interfaces whose values are compile-time constants are initialized first
New Class Instances
Whenever a new class instance is created, memory space is allocated for it with room for all the instance variables declared in the class type and all the instance variables declared in each superclass of the class type, including all the instance variables that may be hidden. All the instance variables in the new object, including those declared in superclasses, are initialized to their default values.
http://en.wikipedia.org/wiki/Double-checked_locking
in Java if a call to a constructor has been inlined then the shared variable may immediately be updated once the storage has been allocated but before the inlined constructor initializes the object.
This leaks the partially initialised object thus putting the system in an inconsistent state.
Hence double-checked locking is unsafe.
This is fixed by using volatile.
// Works with acquire/release semantics for volatile // Broken under Java 1.4 and earlier semantics for volatile class Foo { private volatile Helper helper; public Helper getHelper() { Helper result = helper; if (result == null) { synchronized(this) { result = helper; if (result == null) { helper = result = new Helper(); } } } return result; } // other functions and members... }
Inner classes are not loaded until they are referenced.
Unloading
A class or interface may be unloaded if and only if its defining class loader may be
reclaimed by the garbage collector
Program Exit
A program terminates all its activity and exits when one of two things happens:
- All the threads that are not daemon threads terminate.
- Some thread invokes the exit method of class Runtime or class System and the exit operation is not forbidden by the security manager.
Example 1:
public class WithInstanceFieldsInitialised { private String name; private String doubleName = name+name; public WithInstanceFieldsInitialised(String name){ this.name = name; } public String getDoubleName(){ return doubleName; // Will always return nullnull } }
No comments:
Post a Comment