zoukankan      html  css  js  c++  java
  • JVM类加载机制

    加载:

    1. 通过一个类的全限定名来获取定义此类的二进制字节流(并没有指明要从一个Class文件中获取,可以从其他渠道,譬如:网络、动态生成、数据库等);
    2. 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构;
    3. 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口;

    校验:

      Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全,魔数,元数据校验;-Xverifynone参数来关闭大部分的类验证措施

    准备:

    准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些变量所使用的内存都将在方法区中进行分配

    解析:解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程

    初始化:

      初始化阶段是执行类构造器<clinit>()方法的过程
    <clinit>()方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块static{}中的语句合并产生的

    虚拟机规范严格规定了有且只有5中情况(jdk1.7)必须对类进行“初始化”(而加载、验证、准备自然需要在此之前开始):

    1. 遇到new,getstatic,putstatic,invokestatic这失调字节码指令时,如果类没有进行过初始化,则需要先触发其初 始化。生成这4条指令的最常见的Java代码场景是:使用new关键字实例化对象的时候、读取或设置一个类的静态字段(被final修饰、已在编译器把结 果放入常量池的静态字段除外)的时候,以及调用一个类的静态方法的时候。
    2. 使用java.lang.reflect包的方法对(通过反射对)类进行反射调用的时候,如果类没有进行过初始化,则需要先触发其初始化。
    3. 当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化。
    4. 当虚拟机启动时,用户需要指定一个要执行的主类(包含main()方法的那个类),虚拟机会先初始化这个主类。
    5. 当使用jdk1.7动态语言支持时,如果一个java.lang.invoke.MethodHandle实例最后的解析结果 REF_getstatic,REF_putstatic,REF_invokeStatic的方法句柄,并且这个方法句柄所对应的类没有进行初始化,则 需要先出触发其初始化。

    不会触发初始化:

    1.通过数组定义来引用类,不会触发此类的初始化

    2.(引用常量)常量在编译阶段会存入调用类的常量池中,本质上并没有直接引用到定义常量的类,因此不会触发定义常量的类的初始化

    3.子类来引用父类中定义的静态字段,只会触发父类的初始化而不会触发子类的初始化。

    对象的实例化在类的初始化之前,嵌套初始化,类的静态变类为本类变类的情况

  • 相关阅读:
    Simple Automated Backups for MongoDB Replica Sets
    [转] matlab获取时间日期
    Matlab与C++混合编程 编写独立外部应用程序时出现“无法定位序数3906于动态链接库LIBEAY32.dll上”错误
    Visual Studio 控制台应用程序 同时使用OpenCV和matlab mat文件操作
    [转] Matlab与C++混合编程(依赖OpenCV)
    OpenCV 64位时 应用程序无法正常启动0x000007b 问题解决
    LinkedBlockingQueue多线程测试
    rdlc报告vs2008编辑正常,在vs2012在对错误的编辑
    SD3.0四个协议解读
    链队列
  • 原文地址:https://www.cnblogs.com/lelouchKOP/p/5790694.html
Copyright © 2011-2022 走看看