深入理解JVM-07-虚拟机类的加载机制

一  (1)和c/c+(c在编译阶段进行链接)不同的是   java语言中类型的加载,连接,初始化都是在程序运行期完成的。

二 类加载的时机

(1)类从被加载到虚拟机内存   到卸载出内存为止。

 类的生命周期经过下面7个阶段:

(这里基本按箭头方向顺序开始(不是按部就班的进行或完成,这些阶段会在一个阶段执行过程调用激活另一阶段),解析阶段除外(为了支持java动态绑定(或者叫晚期绑定),某些情况下解析可以在初始化阶  段之后进行)

(2)5种必须对类进行初始化(加载验证准备要在此之前完成)//这5种是对一个类的主动引用,其他称为被动引用

@1   遇到new(new一个对象), getstatic(读一个静态字段), putstatic(写一个静态字段)  ,invokestatic (调用                 static方法) 4个字节码指令

@2    进行反射调用(使用java.lang.reflect包下的方法)

@3    初始化子类时,先要初始化父类

@4   执行main方法的类必须先初始化

@5   使用JDK1.7 的动态语言支持时,如果一个java.lang.invoke.MethodHandle实例解析结果是                                                       REF_getStatic    REF_putStatic  REF_invokeStatic的方法句柄  ,初始化这些方法所在的类。

(3)被动引用(不会初始化)的三个例子

接口的加载过程和类的加载有一些不同:接口并不要求其父接口全部都完成初始化(而子类初始化时,其父类必须全部初始化)

三  类加载过程

(1)在加载(loading)阶段完成三件事-----获取类的二进制字节流

       ----------这个字节流的存储结构 转为 方法区 运行时的数据结构

       ----------在内存中 生成代表这个类的对象, 作为方法区这个类的各种数据的访问路口

数组类的情况有所不同(数组类由java虚拟机直接创建,不通过类加载器创建),但数组类的元素类型最终还是要类加载器创建

数组类创建过程需要遵循以下的规则:------数组类的组件类型是 引用类型, 正常递归加载

        -------- 不是引用类型 JVM把数组标记与引导类加载器关联   

      --------- 可见性一致,不是引用类型,默认public

 

 

(2)验证 (大致会完成4个阶段的检验)(非常重要但不一定必要的阶段)

----------文件格式验证 (CAFEBABE 版本号 )

----------元数据验证 (是否有父类,父类是否final,类是否抽象,是否符合重载规则)

----------字节码验证(方法)(最复杂的一个阶段){确定程序语义是合法的,方法不会出错}

----------符号引用验证(确保解析动作能正常执行)

(3)准备(变量通常为0 false null)

public static int val=123; //准备阶段过后的初始值为0 而不是123,赋值是在初始化阶段

public static final int val=123 //加final 准备阶段过后是123

(4)解析(虚拟机将常量池内的符号引用 替换为直接引用的过程)

解析动作主要针对 类或接口 字段 类方法 接口方法 方法类型 方法句柄和调用点限定符7类符号引用进行

(5)初始化(是类加载过程的最后一步)

 static int i=0; static{ } static{ }能访问 i 定义在static{ }后面的只能赋值不能访问

四 类加载器

双亲委派模型

(某个特定的类加载器在接到加载类的请求时,首先将加载任务委托给父类加载器,依次递归,如果父类加载器可以完成类加载任务,就成功返回;

只有父类加载器无法完成此加载任务时,才自己去加载。)

public class Demo04 {
    /**
     * 
     * Bootstrap ClassLoader   启动类加载器
     * Extension ClassLoader   扩展类加载器  //ext的目录下
     * ApplicationClassLoader  应用程序类加载器//一般程序默认的加载器
     *
     * User ClassLoader  用户自定义的类加载器
     */

    public static void main(String[] args) {
        Object obj=new Object();
        Person p=new Person();
        System.out.println(obj.getClass().getClassLoader());//null
        System.out.println(p.getClass().getClassLoader().getParent());//sun.misc.Launcher$ExtClassLoader@a15670a
    }
}

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值