Jul 11, 2015 ruochenxing java classload

JVM类加载机制

一、类加载的时机

有且只有5中情况 ## 二、类加载过程
1.加载:查找并装载类型的二进制数据到虚拟机中
	通过一个类的全限定名来获取定义此类的二进制字节流
	将字节流所代表的静态存储结构 转化为 方法区的运行时数据结构
	在内存中生成一个代表这个类的Class对象,作为方法区中这个类的各种数据的访问入口
	注意:Java虚拟机规范允许类装载器缓存Java类型的二进制表现形式,如果预装载出错,则要等待该类被主动使用时抛出LinkageError的子类的异常 
2.链接
	1)验证:确保导入的类格式正确
		为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求
			文件格式验证
			元数据验证
			字节码验证
			符号引用验证
		注意:Java虚拟机设计者可以决定如何及时验证类型。Java虚拟机规范列出了虚拟机可以抛出的异常以及在何种条件下必须抛出它们
	2)准备:为类变量分配内存,设置默认初始值
		正式为 类变量 分配内容并设置类变量初始值(默认值)的阶段,这些变量所使用的内存都将在方法区中进行分配
		对于被final修饰的类变量,则会在准备阶段被赋值
		假设一个类变量的定义为:
			public static int value=123;
		则在准备阶段,value的值会设置为默认值0而不是123(value赋值为123的putstatic指令是程序被编译后,存放在类构造器<clinit>()方法中,所以value赋值为123的动作会在初始化阶段才会执行)
		但是,如果类字段的字段属性表中存在ConstantValue属性,那么准备阶段变量value就会被初始化为ConstantValue的值
		假设一个类变量定义为
			public final static int value=123;
		编译时javac将会为value生成ConstantValue属性,在准备阶段,value的值会设置为123而不是0
	3)解析:把类型中的符号引用转换为直接引用(也可能推迟到真正需要使用某个符号引用时再去解析它)
		在类型的常量池中寻找类,接口,字段和方法的符号引用,把类型中的符号引用转换为直接引用
		在使用操作符号引用的字节码指令之前,先对它们所使用的符号引用进行解析
		虚拟机将常量池中的符号引用替换为直接引用的过程
		符号引用:类和接口的全限定名、字段的名称和描述符、方法的名称和描述符
		直接引用:直接指向目标的指针、相对偏移量、一个能间接定位到目标的句柄,如果有了直接引用,那引用的目标必定已经在内存中存在
		解析主要针对类,接口,字段,类方法,接口方法,方法类型,方法句柄,调用点限定符等7类符号引用进行
3.初始化
	1.如果类存在直接超类,且直接超类还没有初始化,则先初始化直接超类
	2.如果类存在一个类初始化方法(“<clinit>”,并不是所有的类都存在这个方法,如果一个类没有类变量也没有静态初始化语句,就没有该方法),就执行它
	所有的类变量初始化语句和类型的静态初始化器都被Java编译器收集在一起,放到一个特殊的方法(“<clinit>”)中,称为类初始化方法,此方法只能被Java虚拟机调用
	真正开始执行Java代码(字节码)的阶段
	在初始化阶段,虚拟机根据程序代码去初始化 类变量和其他资源,也就是执行类构造器<clinit>()方法的过程
	<clinit>()是由编译器自动收集类中的 所有类变量的赋值操作和静态代码块中的语句 合并产生的,编译器收集的顺序为代码中定义的顺序,如果一个类中没有静态代码块,也没有类变量的赋值操作,则不产生<clinit>()方法。
	父类<clinit>()先执行,父接口不会,且<clinit>()方法是线程安全的

	所有的Java虚拟机实现必须在每个类或接口首次主动使用时初始化。有以下六种
	1)当创建某个类的新实例时,或者在字节码中执行new指令,或者通过不明确的创建、反射、克隆或者反序列化时。
	2)当调用某个类的静态方法时(即在字节码中执行invokestatic指令)
	3)当使用某个类或接口的静态字段,或者对该字段赋值时(即在字节码中执行getstatic或putstatic指令时,用final修饰的静态字段除外,它被初始化为一个编译时的常量表达式)
	4)当调用Java API的某些反射方法时,比如类Class中的方法或者java.lang.reflect包中的类的方法
	5)当初始化某个类的子类时(除接口外)
	6)当虚拟机启动时某个被表明为启动类(含有main方法)的类
	除以上六种情形外,所有其它使用Java类型的方式都是被动使用,都不会导致Java类型的初始化

Share this post

Search widget

Timeline

Friendly Links