虚拟机类加载机制和new对象的过程

虚拟机类加载机制:

    类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载验证准备,解析,初始化,使用和卸载7个阶段。其中验证、准备、解析三个阶段成为连接。加载、验证、准备、初始化和卸载这几个阶段的顺序是固定的,解析阶段则不一定,它在某些情况下可以在初始化阶段之后再开始,这是为了支持java语言的运行时绑定(也称为动态绑定或晚期绑定)。

new对象的过程:

A a=new A();
  1. 首先去JVM的方法区中寻找类的class对象,如果能找到,则按照定义生成对象,找不到转2;
  2. 加载类定义:类加载器寻找该类的.class文件,找到后对文件进行分析转换为class对象存入方法区方便以后调用,JDK的class一般是在JVM启动时使用启动类加载器完成加载,用户的class则是在用到的时候再加载;                                            Java中的ClassLoader的加载采用了双亲委派模型,采用双亲委派模型加载类的时候采用如下的几个步骤:                          (1)当前ClassLoader首先从自己已经加载的类中查询此类是否已经被加载,如果已经被加载则直接返回原来已经加载的类。每个类加载器都有自己的加载缓存,当一个类被加载了以后就会放入缓存,等下次加载的时候就可以直接返回了;      (2)当前ClassLoader的缓存中没有找到被加载的类的时候,委托父类加载器去加载,父类加载器采用同样的策略,首先查看自己的缓存,然后没有的话委托父类的父类去加载,一直到Boostrap ClassLoader.                                                        (3)当所有的父类加载器都没有加载的时候,再由当前的类加载器加载,并将它放入自己的缓存中,以便下次有加载请求时直接返回。
  3. 在JVM的堆中给对象开辟一个内存空间;
  4. 对象初始化,顺序如下:
  5. 先初始化父类的静态属性,再初始化父类的静态代码块;
  6. 再初始化子类的静态属性,再初始化子类的静态代码块;
  7. 初始化父类的特有属性;
  8. 初始化父类的构造代码块;
  9. 初始化父类对象相应的构造方法;
  10. 初始化子类的特有属性;
  11. 初始化子类的构造代码块;
  12. 将子类的内存地址赋给栈中的引用对象。

PS.为什么要采用这样的委托机制?

    理解这个问题,先引入另外一个关于ClassLoader的概念“命名空间”,指的是要确定一个类,需要类的全限定名以及加载此类的ClassLoader来共同确定。也就是说即使两个类的全限定名是相同的,但是因为不同的ClassLoader加载了此类,那么在JVM中它就是不同的类。明白了命名空间以后,我们再来看委托模型,采用了委托模型以后加大了不同ClassLoader的交互能力,比如上面说的,JDK本生提供的类库,比如hashmap、linkedList等,这些类由boostrap类加载器加载了以后,无论程序中有多少个类加载器,那么这些类其实都是可以共享的,这样就避免了不同的类加载器加载了同样名字的不同类以后造成混乱。

猜你喜欢

转载自blog.csdn.net/hellodake/article/details/81630073