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了。



  • 相关阅读:
    前台传入的application/json;charset=UTF-8格式的数据,java后端从request中获取json数据
    vue-element-admin实战 | 第二篇: 最小改动接入后台实现根据权限动态加载菜单
    vue-element-admin
    进程间通信的几种方式以及线程间通信的几种方式
    vue调用api接口解决跨域问题
    C#多态性(函数重载)
    VirtualBox中安装CentOS7后无法上网的解决方案
    C#继承
    android通过url下载文件
    python的数据爬取
  • 原文地址:https://www.cnblogs.com/shangwne/p/3617526.html
Copyright © 2011-2022 走看看