zoukankan      html  css  js  c++  java
  • JVM002Class初始化过程是什么

    类加载过程大致分为:加载、连接(1验证 2准备 3解析)、初始化,使用和卸载都是已经加载完之后,属于类的生命周期的两个阶段。

     1.类的初始化阶段,事真正开始执行类中定义的java程序代码(字节码)并按程序员的意图去初始化变量的过程,更直接的说,初始化阶段就是执行构造器<clinit>()方法的过程。<clinit>()方法是由编译器自动收集类中的所有类变量的赋值动作和静态代码块static{}中的语句合并产生的,其中编译器收集的顺序是由语句在源文件中出现的顺序所决定,重点就是类变量和静态代码块按源文件中定义的顺序决定执行顺序。

    2.类初始化顺序:

    (1)静态变量、静态初始化块

    (2)普通成员变量、初始化代码块

    (3)构造器

    3.类初始化的详细过程:

    (1)每个类都有一个初始化锁LC,线程获取LC,这个操作会导致当前线程一直等待,直到获取到LC锁。

    (2)如果C正在被其他线程初始化,当前线程会释放LC锁进入阻塞状态,并等待C初始化完成。此时当前线程需要重试这一个过程。执行初始化的过程时,线程的中断状态不受影响。

    (3)如果C正在被本线程初始化,即递归初始化,释放LC并且正常返回。

    (4)如果C已经初始化完成,释放LC并且正常返回。

    (5)如果C处于错误状态,表明不可能再完成初始化,释放LC并抛出异常NoClassFoundError异常。

    (6)否则,将C标记为正在被本线程初始化,释放LC;然后,初始化哪些final且为基础类型的类成员变量。

    (7)如果C是类而不是接口,且C的父类Supper Class和哥哥接口还没有初始化,那么就在SC上面递归的进行完整的初始化过程,如果有必要,需要先验证和准备SC;

    如果SC或初始化过程中抛出异常,则获取LC,将C标记为错误状态,并通知所有正在等待的线程,然后释放LC,然后再抛出同样的异常。

    (8)从C的classloader处获取assertion断言机制是否被打开。

    (9)接下来,按照文本顺序执行类变量初始化和静态代码块,或接口的字段初始化,把它们当作是一个个单独的代码块。

    (10)如果执行正常,那就获取LC,标记C对象为已初始化,并通知所有正在等待的线程,然后释放LC,正常退出整个过程。

    (11)否则,如果抛出了异常E那么会中断退出,如果E不是Error,则以E为参数创建新的异常。

    (12)获取LC,将C标记为错误状态,通知所有等待的线程,释放LC,并抛出异常E。

    父类与子类初始化顺序:Java父类与子类执行顺序 - Sempron2800+ - 博客园 (cnblogs.com)

  • 相关阅读:
    vpp + vxlan
    vpp + frrouting
    VPP + vxlan
    dpdk: Unsupported PCI device 0x19e5:0x0200 found at PCI address 0000:05:00.0
    How-to: Build VPP FD.IO with Mellanox DPDK PMD on top CentOS 7.7 with inbox drivers.
    vpp[73384]: register_node:485: process stack: Invalid argument (errno 22)
    鲲鹏920上vpp--dpdk编译
    编译frr--python版本问题--Python-3.7.7
    安装vpp
    Go排序
  • 原文地址:https://www.cnblogs.com/asenyang/p/15575633.html
Copyright © 2011-2022 走看看