JVM类加载机制

in 编程
关注公众号【好便宜】( ID:haopianyi222 ),领红包啦~
阿里云,国内最大的云服务商,注册就送数千元优惠券:https://t.cn/AiQe5A0g
腾讯云,良心云,价格优惠: https://t.cn/AieHwwKl
搬瓦工,CN2 GIA 优质线路,搭梯子、海外建站推荐: https://t.cn/AieHwfX9

类加载过程可分为七个阶段:

  1. 加载:加载文件;
    • 通过类的完全限定名来获取类的二进制字节流(来源不限,zip、网络、数据库,动态生成等);
    • 将字节流所代表的文件结构,转换成方法区的运行时数据结构;
    • 在堆中创建一个代表该类的java.lang.Class对象,作为访问在方法区内该类的外部入口;
  2. 验证:验证字节流是否符合JVM规范,保证其不会威胁到JVM的安全;
    • 文件格式验证:字节码文件格式;
    • 元数据验证:字节码内容分析,是否符合JAVA语言规范;
    • 字节码验证:对类的方法体做校验;
    • 符号引用验证:验证符号引用的类、方法等是否可以找到,是否可以访问等;
  3. 准备:为类变量分配内存并赋初始值;
    • static变量赋“零值”,比如int=123,赋值为0;
    • final static变量直接赋初始值,比如int = 123,赋值为123;
  4. 解析:将常量池内的符号引用转换位直接引用的过程(静态解析);
    • 符号引用:用符号代替目标的引用,比如,用class_name_method代替某一个方法,可以是任何形式的字符,只要能找到,没有歧义;引用的目标不一定已经加载到了内存;
    • 直接引用:可以是直接指针,或者简洁能访问到到句柄,具体和虚拟机的实现有关;这时候目标已经加载到了内存;
  5. 初始化:按照用户代码中的要求,对一些属性赋初始值;或者叫执行类构造器(clinit)方法的过程;
    • 虚拟机自动创建、执行,内容包括类变量的赋值(static int = 123;)、类静态块代码(static{});
    • 父类的类构造器优先执行;
    • 父类接口中的类构造器是在内部定义的静态变量被使用时执行,所以不一定是优先子类执行;
    • 多线程情况下,如果clinit中有耗时长操作,会出现阻塞的情况;
  6. 使用:用户程序中使用类;
  7. 卸载:在这些类不再被使用时,从JVM中卸载删除;

类加载器

  1. Bootstrap ClassLoader:启动类加载器,加载java_home\lib下的类;开发者不可使用;
  2. Extension ClassLoader:扩展类加载器,加载java_home\ext下单类;开发者可以使用;
  3. Application ClassLoader:应用程序加载类:加载用户类classpath上所指定的类;开发者可以使用;
  4. 自定义 ClassLoader:用户通过重写抽象类 ClassLoader中的findClass()方法自定义;

可以重写loadClass方法,但是不建议;

 

双亲委派机制

一个类加载器收到一个类加载到请求,优先委派给父加载器来加载,如果父加载器没有加载到该类(在起搜索到的范围内没有找到),才自己加载,每一层都一样;

 

两个类是否相同的判断依据

  1. 被同一个类加载器加载完成;
  2. 类的完全限定名相同;

 

字节码执行引擎

栈帧:

虚拟机进行方法调用和执行的数据结构,存储了方法的局部变量表、操作数栈、动态连接、方法返回地址等信息;局部变量表的大小,栈帧的深度在编译期间就已经确定了,保存在方法表的Code属性中;

  • 局部变量表:方法的入参、方法内部定义的局部变量;
  • 操作数栈:比如int a,b; a+b;,需要先入a,再入b,再出b,再出a,相加计算,结果再入栈;
  • 动态连接:每个栈帧包含一个执行运行时常量池中该栈帧所属方法的引用;
  • 方法返回地址:该方法被调用的位置,用户方法执行结束,程序能继续执行;

每个方法的调用和返回,对应的是虚拟机栈中一个栈帧的入栈和出栈过程;

执行方式

  1. 解释执行;v1.0之前是解释执行;
  2. 编译执行;当前的版本是二者配合执行或者某一种,可以指定;

 

指令集:

  1. 基于栈:数据存放在内存中(JAVA选择了基于栈的指令集)
    1. 优点:平台的可移植性(在用户和硬件之间加了一层),代码相对紧凑,编译实现更加简单;
    2. 缺点:相对于基于寄存器的指令集,要慢;
  2. 基于寄存器:数据存放在寄存器;

编译器

  1. 前端编译器:.java文件编译成.class字节码文件;
    1. 解析与填充符号表;
      1. 解析:词法、语法分析;
        1. 词法分析:将字符流转换为标记(token)集合;
        2. 语法分析:根据标记序列生成抽象语法树;
      2.  填充符号表:
    2. 注解处理;
    3. 分析并生成字节码;
  2. JIT编译器:运行时编译,再运行到过程中,将.class文件编译成机器码;
  3. AOT编译器:在运行之前,将.java文件编译成本地机器码;

 

编译过程(参考MySQL的语句执行过程)

  1. 获取程序源码
  2. 词法分析->单词流
  3. 语法分析->语法数
  4. 执行

 

编译优化

早期(前端编译期)优化:

  • 泛型与类型擦除
  • 自动装箱、拆箱
  • 遍历循环替换
  • String累加
  • 条件编译(if(true)等)
  • 等等……

晚期(JIT编译期)优化:

  • 公共子表达式消除
  • 数组范围检查消除
  • 方法内联
  • 逃逸分析,结果可以支持:栈上内存分配、同步消除、标量(无法再分解的数据)替换(用基础数据替换对象);
  • 热点代码探查
  • 指令重排
关注公众号【好便宜】( ID:haopianyi222 ),领红包啦~
阿里云,国内最大的云服务商,注册就送数千元优惠券:https://t.cn/AiQe5A0g
腾讯云,良心云,价格优惠: https://t.cn/AieHwwKl
搬瓦工,CN2 GIA 优质线路,搭梯子、海外建站推荐: https://t.cn/AieHwfX9
扫一扫关注公众号添加购物返利助手,领红包
Comments are closed.

推荐使用阿里云服务器

超多优惠券

服务器最低一折,一年不到100!

朕已阅去看看