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

    本篇文章讲述虚拟机如何加载Class文件和Class文件中的信息进入到虚拟机后会发生什么变化

    1.类加载的时机

    类被加载到虚拟机的内存中,他的整个生命周期包含了:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸载(Unloading)七个阶段,其中验证、准备和解析三个部分称为链接(Linking)。


    对于什么阶段开始类加载的第一个阶段:加载,在虚拟机的规范中没有约束,但是对于初始化阶段,虚拟机则严格对四种情况进行了要求必须对类进行初始化

    1.遇到new、getstatic、putstatic或者invokestatic这四条字节码指令的时候(场景:即使用new关键字实例化对象的时候,读取或者设置一个类的静态字段的时候,以及调用一个静态的方法的时候)

    2.使用java.lang.reflect包的方法对类进行反射调用的时候,如果类没有进行过初始化,则需要触发其初始化

    3.当初始化一个类的时候,如果一个类的父类还没有进行初始化,则要先触发父类的初始化。

    4.当虚拟机启动的时候,虚拟机会先初始化包含main方法的那个主类


    比如:在A类中引用B类中的静态字符串常量b,在编译的时候,对常量B.b的引用实际都被转化为A类对自身的常量池的引用了,两个类在编译成Class之后就不存在任何联系了。

    接口的加载:编译器会为接口生成“<clinit>()”类构造器,用于初始化接口的成员变量,接口和类的真正区别是上面的3,在一个接口初始化的时候,并不会要求其父接口全部都初始化,只有真正用到父接口的时候(如引用接口中定义的常量)才会初始化。


    类加载的过程

    就上面的加载~初始化五个阶段

    1.加载阶段 :1)通过类的全限定名获取定义此类的二进制字节流  2)将这个字节流的静态存储结构转化为方法区的运行时数据结构 3)在堆中生成java.lang.Class对象,作为方法区的访问入口

    2.验证阶段:主要是确保Class文件的字节流包含的信息符合要求虚拟机的要求,不会危害计算机(具体过程很复杂)

    3.准备阶段:正式为类变量分配内存并设置类变量的初始值的阶段,这些内存都在方法区分配,需要强调的是,这里分配的内存仅包括类变量,不包括实例变量,实例变量将会在对象的实例化时一起分配到Java堆中,这里说的初始值指的是类变量的零值,例如 public static int a = 56,在准备阶段时,a=0.其赋值是在类的构造器的<clinit>()的方法之中,赋值阶段将会在初始化阶段才会被执行。如果是public static final int a = 56 在准备阶段就是a = 56了。



  • 相关阅读:
    java 在线网络考试系统源码 springboot mybaits vue.js 前后分离跨域
    springboot 整合flowable 项目源码 mybiats vue.js 前后分离 跨域
    flowable Springboot vue.js 前后分离 跨域 有代码生成器 工作流
    Flowable 工作流 Springboot vue.js 前后分离 跨域 有代码生成器
    java 企业 网站源码 后台 springmvc SSM 前台 静态化 代码生成器
    java 进销存 商户管理 系统 管理 库存管理 销售报表springmvc SSM项目
    基于FPGA的电子计算器设计(中)
    基于FPGA的电子计算器设计(上)
    FPGA零基础学习:SPI 协议驱动设计
    Signal tap 逻辑分析仪使用教程
  • 原文地址:https://www.cnblogs.com/shangwne/p/3617526.html
Copyright © 2011-2022 走看看