虚拟机执行器

简介: 虚拟机执行器

JMV-虚拟机执行器

  • 总纲

Class结构

  • Class文件是一组以八个字节为基础单位的二进制流
  • Class文件有两种基础数据类型
  • 无符号数:基本的数据类型,由u1,u2,u4,u8代表1,2,4,8个字节的无符号数;可用于描述数字、索引引用、数量值或者按照UTF-8编码构成字符串值
  • 表:是由多个无符号数或者其他表作为数据项构成的复合数据类型
  • Class具体结果如下:
  • Class文件各数据项的具体含义
类型 名称 数量 含义
u4 magic 1 (魔数)判断Class文件是否被JVM接受?
u2 minor_version 1 次版本号
u2 major_version 1 主版本号
u2 constant_pool_count 1 常量池容量计数器
cp_info constant_pool constant_pool_count-1 常量池
u2 access_flags 1 识别类或者接口层次的访问信息
u2 this_class 1 类索引
u2 super_class 1 父类索引
u2 interfaces_count 1 接口索引数目
u2 interfaces interfaces_count 该类实现的接口索引
u2 fields_count 1 字段数目
field info fields fields_count 接口或者类中申明的变量
u2 methods_count 1 方法数目
method_info methods methods_count 该类中的方法
u2 attributes_count 1 属性表数目
attribute info attributes attributes count 属性表集合
  • 常量池
  • 字面量:字面量比较接近于Java语言层面的常量概念,如文本字符串、被声明为final的常量值
  • 符号引用:符号引用则属于编译原理方面的概念
  • JVM类加载机制
  • 什么是JVM的类加载机制?
  • 把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这个过程被称作虚拟机的类加载机制
  • JVM加载流程;如图:
  • 加载、验证、准备、初始化和卸载这五个阶段的顺序是确定的
  • 解析阶段的顺序不一定;这是为了支持Java语言运行时绑定的特性
  • 何时进行初始化?:
  • 遇到new、getStatic、putStatic或invokeStatic这四条字节码指令时,如果类型没有进行过初始化,则需要先触发其初始化阶段.
  • 反射调用时,若该对象未初始化
  • 初始化类时,父类未初始化
  • JVM启动时,优先初始化指定的类
  • 接口中定义了default方法,若接口的实现类发生初始化,则接口优先初始化
  • 加载(Loading)阶段:
  • 通过类的全限定类名获取字节流
  • 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
  • 在内存中生成该类的java.lang.Class对象,作为方法区此类的各种数据的访问入口
  • 验证阶段(Verification):
  • 验证Class文件是否符合JVM规范;是否对JVM产生不利影响
  • 包含四个阶段:
  • 文件格式验证:验证魔数、版本号、常量池的常量类型等......
  • 元数据验证:验证类的父类存在与否、是否重写final类、是否实现父类的抽象方法等......
  • 字节码验证:分析数据流以及控制流,检查逻辑、语义是否合法
  • 符号引用验证:符号引用转化为直接引用的时候,发生在解析阶段
  • 准备阶段(Preparation):
  • 为类变量(static修饰的变量)初始化,分配内存并且赋予初始值(并非硬编码设置的值,而是系统的值)的阶段
  • 类变量理论上应该存在方法区,但是实际上在JDK8中却存在于堆
  • 解析阶段(Resolution):
  • 将常量池中类变量的符号引用转变成为直接引用
  • 符号引用(与内存无关):以一组符号来描述所引用的目标,符号可以是任何 形式的字面量,只要使用时能无歧义地定位到目标即可
  • 直接引用(与内存有关):可以直接指向目标的指针、相对偏移量或者是一个能 间接定位到目标的句柄
  • 初始化阶段(Initialization):
  • 依据编码的主观计划去初始化变量以及资源
  • 初始化阶段是执行<clinit>方法的过程
  • <clinit>是由类中的static代码块、变量组成的
  • <clinit>、<init>方法的区别
  • <init>对于非static变量赋值,<clinit>对static对象赋值
  • <init>对象在实例化对象时发生;<clinit>在JVM类加载的初始化阶段发生
  • 类加载器
  • 双亲委派模型
  • 什么是双亲委派模型?
  • 如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加 载这个类,而是把这个请求委派给父类加载器去完成,只有当父加载器反馈认为无法加载时,才会自己加载
  • 双亲委派模型如图所示:
  • 双亲委派各级加载器之间不是继承关系,而是包含关系
  • Java语言的双亲委派实现
  • 首先确定是否存在目标类
  • 存在则直接返回
  • 否则确定父级Class加载器是否存在(递归过程),如果存在父级加载器则使用父级加载器实现
  • 如果不存在父类加载器,则证明自身为根加载器,则使用跟加载器加载Class
  • 如果以上加载过程都不能加载Class,则使用自身的ClassLoader加载Class
  • 双亲委派适用于用户需要依赖于核心文件;不适用于核心文件依赖用户资源(如下:)
  • 双亲委派的缺陷:父加载器无法访问子加载器(如:DriverManager需要根据用户的需求加载不同的Class)
  • 为什么需要双亲委派模型?
  • 确保每一个Class文件对于每一个Class加载器都是唯一的;保证Class文件的唯一性;
  • 防止自定义Class文件污染JVM自带的Class;保证JVM的安全性
  • 各级类加载器的区别
  • 启动类加载器(Bootstrap Class Loader):负责加载存放在 <JAVA_HOME>\lib目录;由C++实现,属于JVM本身的一部分
  • 扩展类加载器(Extension Class Loader):负责加载<JAVA_HOME>\lib\ext目录
  • 应用程序类加载器(Application Class Loader):它负责加载用户类路径 (ClassPath)上所有的类库
  • 如何破除双亲委派?
  • 由Java源码可知,如果父类加载器加载失败,会触发findClass(name)方法,因此重写findClass(name)即可
  • SPI(Service Provider Interface)机制的引入,由于系统自带的ClassLoader不认识SPI中的全路径类名;因此需要其余的类加载器去加载SPI的类,引入了线程上下文类加载器 (Thread Context ClassLoader)
目录
相关文章
|
Linux 虚拟化
此虚拟机的处理器所支持的功能不同于保存虚拟机状态的虚拟机的处理器所支持的功能
此虚拟机的处理器所支持的功能不同于保存虚拟机状态的虚拟机的处理器所支持的功能
1410 0
此虚拟机的处理器所支持的功能不同于保存虚拟机状态的虚拟机的处理器所支持的功能
|
测试技术 虚拟化 Windows
虚拟机的运行架构
虚拟机作为应用软件安装在操作系统上 可以在此应用软件上安装多个操作系统 直接安装在硬件上的系统为宿主
108 0
虚拟机的运行架构
|
运维 监控 Java
JVM07-虚拟机故障处理之命令行工具
上一篇我们介绍了JVM06-经典垃圾收集器。这篇文章将介绍用来排查处理虚拟机故障的一些常用的命令行工具。因为如果我们要对JVM进行调优时,必须要通过这些工具分析虚拟机的运行状态。
101 0
JVM07-虚拟机故障处理之命令行工具
|
存储 安全 前端开发
JVM | 第2部分:虚拟机执行子系统《深入理解 Java 虚拟机》
第2部分主题为虚拟机执行子系统,以此延伸出 class 类文件结构、虚拟机类加载机制、虚拟机字节码执行引擎等相关内容;
173 0
JVM | 第2部分:虚拟机执行子系统《深入理解 Java 虚拟机》
|
固态存储 内存技术
虚拟机操作脚本
手动定制虚拟磁盘格式,通过脚本添加不同类型的模拟磁盘,增加磁盘的硬件信息
231 1
|
监控 Java
虚拟机参数
关于虚拟机参数,总体有两大类: -XX 对于系统级别的(jvm)配置,配置日志信息,或者说配置jvm使用什么样的垃圾回收器。 非-XX的 基本上都是对应用层面上的配置。
1016 0
|
Java C++ 索引
深入理解虚拟机之虚拟机字节码执行引擎
执行引擎是java虚拟机最核心的组成部件之一。虚拟机的执行引擎由自己实现,所以可以自行定制指令集与执行引擎的结构体系,并且能够执行那些不被硬件直接支持的指令集格式。
8810 0
|
存储 Java 索引
虚拟机执行引擎
本博客为《深入理解java虚拟机》的学习笔记,所以大部分内容来自此书,另外一部分内容来自网络其他博客和源码分析。 主要内容包括:虚拟机执行引擎的机构;方法调用过程;方法分派(即java支持方法多态,调用中如何确定方法版本的问题)。
2393 0
|
Java 编译器 自然语言处理
虚拟机优化
本博客为《深入理解java虚拟机》的学习笔记,所以大部分内容来自此书,另外一部分内容来自网络其他博客和源码分析。 主要内容包括:前期(编译期)优化,后期(运行期)优化。   一  前期(编译期)优化 1       编译过程 从javac的角度来看,编译过程大致分为三步: Ø  解析与填充符号表过程。
1703 0