zoukankan      html  css  js  c++  java
  • JVM类加载机制—结合代码分析

    《深入理解Java虚拟机》学习笔记


    首先看下面的两个类

    这里写图片描述

    对于被主动引用的类,执行类加载操作,根据给定的全限定名获取这个类的二进制字节流(不一定是class文件,网络、动态代理等方式也会)并将二进制按虚拟机要求的格式存储在方法区(HotSpot存储用于访问方法区中这些类型的外部接口Class对象)。

    当注释掉main方法中对Test类的实例化语句后,
    这里写图片描述
    可以看到,这里对父类、子类的static域进行了初始化,而构造函数没有涉及。对比得到:

    当调用main()方法时初始化这个类(其实main也是一个静态方法),或当初始化子类时,会自动初始化未初始化的父类

    当我们加入一个TestUnlce类,区别在于多了一个静态方法如下:

    1.当在Test的main()方法中有下列三条语句的其中之一

    输出如下:
    这里写图片描述

    2.但是若语句如下,调用final修饰的static字段时:

    执行结果如下:
    这里写图片描述

    当遇到new(使用new关键字实例化对象)、getstatic(读取一个类的非final修饰静态字段)、putstatic(设置一个类的静态字段)、invokestatic(调用一个类的静态方法)方法时,对相应的类执行初始化操作

    当然,情况不只于集中,还存在反射、动态语音支持等,这里就事论事不做深入讨论

    为了确保Class文件中的字节流中包含的信息符合当前虚拟机的要求,并不会危害自身安全。总的来说,就是在字节流中验证文件格式是否正确(就像是否存在魔数0xCAFEBABE、主次版本号是否能处理),对元数据进行语义分析。
    最后一个阶段在于在JVM将符号引用化为直接引用时,验证类的各种修饰是否合法。

    当我们对class文件的魔数或者版本号进行非法修改时:
    这里写图片描述
    这里写图片描述
    大概效果如下,由于存在编码问题,主要的是问题的根源:
    这里写图片描述

    就像当我们使用Test**调用了一个不存在的方法**时:
    这里写图片描述

    对于上述情况,就会出现不同的Error,JVM会直接中断类加载过程而拒绝继续编译。

    准备阶段即正式为类变量(static修饰的变量,不包括实例变量,实例变量会在对象实例化时一起分配在堆中)分配内存并设置初始值的阶段。对应到例子中的一直存在的两个类变量:

    对于static修饰的y,此处被分配内存空间并赋值为int类型的初始默认值0;
    对于static final修饰的y,它是一个有ConstantVlaue属性的字段,则会被直接完成赋值为10;

    这些变量使用的内存都将在方法区中分配

    解析阶段是JVM将常量池内的符号引用替换为直接引用的过程(此时与验证阶段存在交叉关系)

    
    

    解析动作主要针对类、接口、字段、类方法、接口方法、方法类型、方法句柄与调用点限定符 7种符号引用。若出现不符合JAVA规范的情况,会抛出Error,就像验证阶段。

    终于到了类加载的最后一步初始化!,在准备阶段变量已经被赋予过初始值,预科是什么初始化阶段就到了按程序猿要求执行赋值的时候了。实际上:
    初始化阶段是执行类的构造器的过程

    
    

    编译器收集的顺序是由语句在源文件中出现的顺序来决定的,静态语句块只能访问到定义在静态语句块之前的变量,对于之后的,只能赋值,不能引用

    修改上述Test类至如下代码:

    这里写图片描述

    下面再说一个关于的规则:重新构造代码如下

    这里写图片描述

    JVM会保证子类的方法执行之前,父类的已经执行完毕,所以第一个完成的是java.lang.Object,由于父类先执行了,所以父类的static语句块要优于子类的变量赋值

    到此,我们就可以明白一开头的输出情况是怎么出来的


    到此,类加载过程就完成,接下来就是使用了。

  • 相关阅读:
    Delphi线程的终止
    Delphi线程简介---Create及其参数、Resume、Suspend
    谈谈Delphi中的类和对象4---类是一种对数据和操作高度的封装机制 && 类是一种代码重用机制
    LeetCode:链表排序
    LeetCode 二叉树的最小深度
    hadoop的集群安装
    java线程池分析和应用
    Java thread中对异常的处理策略
    Thread interrupt方法解析
    如何偷Android的内存-Tricking Android MemoryFile
  • 原文地址:https://www.cnblogs.com/xiongjim/p/9687478.html
Copyright © 2011-2022 走看看