JVM第一篇 — JVM中类的生命周期

    类从JVM对其加载到卸载,它的整个生命周期包括如下几个阶段:html

  • 加载(Loading)
  • 链接(Linking)
  • 初始化(Initialization)
  • 使用(Using)
  • 卸载(Unloading)

    其中,链接(Linking),又分为验证(Validation)、准备(Preparation)、解析(Resolution)3个子阶段。java

1 类的加载(Loading)

    在加载阶段,JVM主要完成三件事:算法

    1. 经过类的全限定名来查找、获取定义此类的二进制字节流。数据库

    2. 将这个字节流所表明的静态存储结构转化为方法区中的运行时数据结构。网络

    3. 在Java堆中建立一个表明这个类的java.lang.Class对象,做为方法区中静态数据的访问入口。数据结构

1.1 加载途径

  • 从本地系统直接加载
  • 经过网络下载.class文件
  • 从zip、jar文件中加载.class文件
  • 从专有数据库中提取.class文件
  • 将Java源文件动态编译为.class文件

1.2 加载逻辑

    有如下几种类加载器:函数

  • BootstrapClassLoader(启动类加载器):它加载System.getProperty("sun.boot.class.path")所指定jar,即目录${JAVA_HOME中}/jre/lib、${JRE_HOME中}/jre/lib下的全部jar; Bootstrap ClassLoader由C++实现,它不是ClassLoader的子类,它是顶级的类加载器。spa

  • ExtClassLoader(扩展类加载器):它加载System.getProperty("java.ext.dirs")所指定jar,即目录${JAVA_HOME中}/jre/lib/ext、${JRE_HOME中}/jre/lib/ext下的全部jar; 它是BootstrapClassLoader的子类。code

  • AppClassLoader(应用类加载器):它加载应用程序运行时指定的classpath下的jar; 它是ExtClassLoader的子类。htm

public static void main(String[] args) {
        //System.out.println(System.getProperty("sun.boot.class.path"));
        //System.out.println(System.getProperty("java.ext.dirs"));

        Book book= new Book();
        Class c = book.getClass();
        ClassLoader loader = c.getClassLoader();
        System.out.println(loader);
        System.out.println(loader.getParent());
        System.out.println(loader.getParent().getParent());
    }

    以上程序的执行结果为:

sun.misc.Launcher$AppClassLoader@439a8942
    sun.misc.Launcher$ExtClassLoader@56a96eba
    null

    从上面的结果能够看出,并无获取到ExtClassLoader的父Loader,缘由是Bootstrap Loader是用C++语言实现的,找不到一个肯定的返回父Loader的方式,因而就返回null。

    运行一个程序时,老是由AppClassLoader开始加载指定的类,而后它会将加载任务转交给父加载器,父类加载器再将向上转交给BootstrapClassLoader; 若是父类加载器找不到类文件,则逐层由子类加载器处理。

2 类的链接(Linking)

    类的链接(Linking),又分为验证(Validation)、准备(Preparation)、解析(Resolution)三个子阶段。

2.1 验证(Validation),验证的做用是保证Class文件的字节流包含的信息符合JVM规范,不会给JVM形成危害。若是验证失败,就会抛出一个java.lang.VerifyError异常或其子类异常。类的验证内容有:

  • 文件格式验证:验证字节流文件是否符合Class文件格式的规范,而且能被当前虚拟机正确的处理。
  • 元数据验证:是对字节码描述的信息进行语义分析,以保证其描述的信息符合Java语言的规范。
  • 字节码验证:主要是进行数据流和控制流的分析,保证被校验类的方法在运行时不会危害虚拟机。

2.2 准备(Preparation)     准备阶段要作的事情就是为静态变量分配内存并设置默认值。在这个阶段分配的仅为类的static变量,而不包括类的实例变量。

2.3 解析(Resolution)     解析阶段要作的事情就是将方法区常量池内的符号引用替换成直接引用。有如下四种类型的解析:类或接口的解析、属性解析、方法解析、接口方法解析。

3 类的初始化(Initialization)

    类的初始化就是把类的变量(包括实例变量)初始化为正确的值、并执行 static{}块、构造函数等。

3.1 初始化时机

    何时会执行类的初始化呢?

  • 调用new建立类的实例;
  • 初始化类的子类;
  • 访问类或接口的静态变量;
  • 调用类的静态方法;
  • 调用Class.forName()反射建立实例;(ClassLoader.loadClass()也可加载类,但不会执行初始化块)

3.2 初始化步骤

  1. 若是这个类尚未被加载和链接,那先进行加载和链接;
  2. 若是这个类存在直接父类,那就先初始化直接的父类;(注意:在一个类加载器中,每一个类只能初始化一次);
  3. 若是类中存在初始化语句(如static变量、static块),那就依次执行这些初始化语句。
  4. 执行构造函数。

4 类的使用(Using)

    

5 类的卸载(Unloading)

    类的卸载,即指垃圾回收器机制(GC)识别无用对象,并对无用对象占用的内存空间进行回收。垃圾回收机制有如下几种算法(但不限于这几种):

  • 引用计数法(Reference Counting Collector)
  • tracing算法(Tracing Collector)
  • generation算法(Generational Collector)

    关于垃圾回收机制的更多内容,请参考: http://www.importnew.com/16173.html

相关文章
相关标签/搜索