[五]虚拟机执行子系统
以下所有内容来自于 《深入理解 Java 虚拟机》这本书的理解和回顾,非照抄原文,肯定有错误,也有故意致错,一切皆为方便理解
Java 内存区域 奠定了Java 的基础模型,GC 在这其中周而复始,
那么在这之前,在 Java 程序运行之前,jvm 又做了那些事?
# 课前准备 - 类文件结构
类加载的是 class 文件,这里先大概了解以下 class 文件结构
概念
class 文件是专门给 jvm 使用的,对比机器码和操作系统,class 之于 jvm
各个平台上的 虚拟机都统一支持 class 文件
只要是合乎规范的calss文件都能被虚拟机加载
结构 :
将class 文件编译成二进制,前四个字节是“魔数”,用来做身份校验,判断是否是合法的 class 文件,类比猪肉盖章
5.6字节是次版本号,7.8是主版本号,jdk1.0主版本 45 ,新版本 + 1,判断是那个 JDK 编译的,以保证高低版本的兼容性.检测
之后就是常量池入口,访问标志等等,由字段表,属性表,方法表等组成
class 文件包含了一个程序代码的所有内容以及添加的一些额外东西,就像厨师炒菜前把菜品分门别类的准备好,放在一起
字节码指令 :
类似于 x86 指令集,Java 也有自己的指令集 ,指令参数都存放在操作数栈中
Java 虚拟机采用面向操作数栈的架构(桶状),windows 是面向寄存器(蜂窝状),前者效率低,不占空间,后者以空间换时间,
# 类加载
概念:Java 虚拟机把描述类的数据从 class 文件中加载到内存,并对数据进行校验,解析,初始化,最终形成可以直接被虚拟机使用的 Java 类型的过程
Java 的类加载是在程序运行期间完成,比之提前编译好,效率低,扩展性好(运行时可以动态链接)
过程 :
加载:
- classlode 根据 classpath 提供的全限定名获取该类的二进制字节流加载到内存(按照一定规则存放在方法区)
- 由于最终只需要一个二进制字节流,所以可以从任何地方获取,网络,磁盘,压缩包等等
- 加载过程也可以使用用户自定义类加载器
验证:如果有变态通过手敲 0 1 二进制代码,并放入内存,就可能存在安全性
- 文件格式验证:class 文件格式规范
- 元数据验证;对字节码描述的信息进行语义分析
- 字节码验证:验证分析出来的语义是合法的,安全的,由于该过程较为复杂且耗时,官方将尽可能多的验证提前到编译期
- 符号引用:在虚拟机将符号引用转化成直接引用时发生 – 解析式中端发生,检查引用是否存在,合法
准备:
- 静态变量分配内存,并设置初始值(零值,不是程序员代码的初始值)
解析:
- 符号引用替换为直接引用
在此之前的动作都有虚拟机主导完成,之后的步骤则有用户程序接管
初始化:
- 正式根据程序初始化类变量和其他资源
- 初始化阶段就是执行 () 方法的过程
# 双亲委派
在类加载过程中,加载阶段可以自定义类加载器,否则默认使用虚拟机的类加载器
那么虚拟机的类加载器是什么样子呢?
Java 的三层加载器
- 启动类加载器 Bootstrap Class Loader:加载 JDK 下 lib 文件中的类
- 扩展类加载器 Extension Class Loader:加载官方提供的扩展类库的类
- 应用程序类加载器:Application Class Loader:系统类加载器,加载用户类路径上的类库
双亲委派:
加载类时,首现由级别高的加载,没有时,再由下一级加载 ,遇到类加载请求时,先交给父类加载,父类找不到时,再有子类加载
如果一个人写了一个 String 类,里面存在恶意代码,Application Class Loader 直接就把这个类加载到内存中执行了,所有依赖于 String 的类就会有问题,等于是把官方的 String 替换掉了
反之,如果交到 启动类加载器手里,它在核心类库中找到了 官方的 String 类,此时就不会加载用户的恶意 String 的代码了
# 字节码执行
类加载完毕后,就开始执行,由于 Java指令集是基于 栈的,所有操作都在栈上进行
Java 虚拟机以 “栈帧” 作为最基本的执行单元
栈帧需要多大的局部变量表和操作数栈,在编译器已经确定
只有位于栈顶的方法才是运行的,只有位于栈顶的栈帧才是有效的
#分派
Java 中对方法的调用,确定目标方法的过程,多态性的体现,
静态分派:
在编译器确定,在类加载是解析
静态分派只涉及 重载 ,本质是根据方法的参数,确定实际的方法
动态分派:
概念:运行期根据方法接受者的实际类型选择方法版本
方法的重写就是使用动态分派,父子类同名方法是怎么识别的?
静态分派只涉及 重载 ,本质是根据方法的参数,确定实际的方法
动态分派:
概念:运行期根据方法接受者的实际类型选择方法版本
方法的重写就是使用动态分派,父子类同名方法是怎么识别的?
假设 A a = new B(子类),在执行过程中的 invokevirtual 指令,会根据实际类型,也就是 B 找到复合的方法,否则按照继承关系从上到下寻找最合适的方法,如果找不到,就抛出异常,这就是 重写 的本质
[五]虚拟机执行子系统相关推荐
- JVM_虚拟机执行子系统
本篇为<深入理解Java虚拟机 第3版>读书笔记 文中,<Java虚拟机规范>简称<规范> 类文件结构 平台无关性和语言无关性的基石:Java虚拟机和字节码存储格式 ...
- 【Java书笔记】:《深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)》第2部分-自动内存管理,第3部分-虚拟机执行子系统,第5部分-高效并发
作者:周志明 整理者GitHub:https://github.com/starjuly/UnderstandingTheJVM 第2部分-自动内存管理 第2章 Java内存区域与内存溢出异常 2.2 ...
- 深入理解Java虚拟机-虚拟机执行子系统
本博客主要参考周志明老师的<深入理解Java虚拟机>第二版 读书是一种跟大神的交流.阅读<深入理解Java虚拟机>受益匪浅,对Java虚拟机有初步的认识.这里写博客主要出于以下 ...
- JVM——虚拟机执行子系统
摘要 本文将深入的学习与分析JVM虚拟机的原理和相关的调优的相关实例. 虚拟机执行子系统 代码编译的结果从本地机器码转变为字节码, 是存储格式发展的一小步, 却是编程语言发展的一大步.记得在第一节计算 ...
- 第三部分 虚拟机执行子系统
第6章 类文件结构 第7章 虚拟机类加载机制 第8章 虚拟机字节码执行引擎 第9章 类加载及执行子系统的案例 与实战
- Java 虚拟机执行子系统
JVM执行子系统的作用 在当前的Java中,编译器将源代码转成字节码后,字节码通过JVM的字节码执行引擎被执行,执行引擎负责具体的代码调用及执行过程.主要通过输入字节码文件,解析输入字节码,最后输出执 ...
- 深入理解Java虚拟机(第二版) 第九章:类加载及执行子系统的案例与实战
第九章 类加载及执行子系统的案例与实战 9.1 概述 9.2 Tomcat: 正统的类加载器架构 9.3 OSGi:灵活的类加载器架构 9.4 字节码生成技术与动态代理的实现 9.5 Retrotra ...
- JVM学习笔记【2】 类加载执行子系统
1.JVM的简图 简要版 中文的详细版(宋文康老师教学图) 注意:方法区只有HotSpot虚拟机有,J9,JRockit都没有 今天主要的是学习类加载执行子系统 2.类加载执行子系统的作用 类加载器子 ...
- JVM学习第三天(JVM的执行子系统)之开篇Class类文件结构
虽然这几天 很忙,但是学习是不能落下的,也不能推迟,因为如果推迟了一次,那么就会有无数次;加油,come on! Java跨平台的基础: 各种不同平台的虚拟机与所有平台都统一使用的程序存储格式--字节 ...
最新文章
- 隔空测量电压:电场强度测试仪-FMX-004
- MP4移动商学院―――管理者贴身教练!
- Spring Boot Profile
- Android App压力测试(Monkey和ADB)
- Nmap源码分析(主机发现)
- python 飞机大战小游戏
- MaxCompute JOIN优化小结
- python 操作mongodb数据库参考文档
- django项目实现第三方github登录
- 吃货联盟点餐java面向对象_使用面向对象思想编写吃货联盟
- Mac不再丝滑?这些有用的方法了解一下
- Windows server 2012 hyper-v 的实时迁移
- systemctl命令_开发者必备Linux命令
- Android Launcher 应用开发
- 安川机器人原点丢失_安川机器人原点及校准浅析
- 微信拉黑和删好友,哪个更绝情?
- 组装一台计算机的配置,要不要自己动手组装一台电脑?一文告诉你答案!
- 网络Sniffing原理
- 360天擎卸载(2021年亲测有效)
- 数据库MySQL系统实操实验从安装系统到实际操作全过程,五万字系列五,这不直接学完去学校装杯?