- JVM
- 一、阶段梳理
- 1.1 番外资料
- 1.2 编译流程
- 二、JVM
- 2.1 知识点整理
- 2.2 运行时的数据结构
- 程序计数器
- 虚拟机栈
- 本地方法栈
- 堆区
- 方法区
- 运行时常量池
- 直接内存
- 2.3 垃圾回收
- 对象的回收判断算法
- 垃圾收集算法
- 垃圾收集器
- 2.x 对象
- 三、排障工具的使用
- 3.1 概括
- 故障处理工具
- 基础工具
- 安全工具
- 国际化
- 远程方法调用
- Corba
- 部署工具
- 3.2 JVisualVM && Graalvm
- 3.3 JProfiler
- 四、字节码文件与类加载
- 4.1 Class类文件结构
- 4.2 字节码指令
- 4.3 类的生命周期
- 4.4 类的加载过程
- 加载
- 验证
- 准备
- 解析
- 初始化
- 4.5 类加载器
- 4.6 破坏双亲委派模型&&线程上下文类加载器
- 4.7 Java模块化系统
- 五、字节码执行引擎
- 5.1 运行时栈帧的结构
- 5.2 方法调用
- 5.3 动态语言类型支持
- 5.4 基于栈/基于寄存器的指令集
- 六、前端编译优化
- 七、后端编译优化
- over
基于《深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)》
目前主要针对OpenJDK及OracleJDK的HotSpot虚拟机进行学习
一、阶段梳理针对学习路径的一个概括性梳理
1.1 番外资料Java虚拟机(JVM)面试题(2020最新版)_ThinkWon的博客
JVM速成手册 | IT宅-arthinking’s blog
1.2 编译流程(1)Java源文件 (2)编译 (3)生成class字节码文件 (4) JVM加载类
后续的笔记目录也将根据这套流程进行深入分析
二、JVM 2.1 知识点整理- JVM运行时候的数据结构
- 对象的出生过程
- 为对象实例分配内存的方式
- 垃圾回收算法及机制
线程私有 生命周期同线程相同
字节码文件的行号解释器,通过它指定由哪一行代码运行,同样可以实现循环、跳转
但是这是线程私有的,在多线程环境下每个线程执行的字节码文件行号是不一样的
虚拟机栈线程私有 生命周期同线程相同
字面上看,它是一个栈的数据结构
- 每个方法被执行的时候,虚拟机会同步创建一个栈帧
- 栈帧存放了 局部变量表、操作数栈、动态链接、方法出口等信息
- 调用时入栈,用完出栈
运行时栈帧结构_xtayfjpk的专栏-CSDN博客
本地方法栈线程私有 生命周期同线程相同
运行非Java的Native方法,例如fork线程
堆区基本作用
- 存放对象实例
- 受GC堆管理
- 其中又有新生代和老年代的说法
Java中的新生代、老年代、永久代和各种GC 博客园 (cnblogs.com)
方法区- 存储已被加载的类型信息、常量、静态变量等
- 原先永久代使用JVM的内存,现在替换成元空间使用本地内存
- Jdk 8后方法区的字符串常量池给了堆区
1
直接内存1
2.3 垃圾回收上面这些先待定,后期通过做实验观察一下JDK17
对象的出生到死亡,从类加载到GC的回收的心路历程
对象的回收判断算法- 引用计数算法
- 可达性分析算法
- 引用链判断
- 清除算法
- 复制算法
- 整理算法
再看,种类太多了
2.x 对象-
句柄访问
如果使用句柄访问的话,那么Java堆中将会划分出一块内存来作为句柄池,reference中存储的就是对象的句柄地址,而句柄中包含了对象实例数据与类型数据各自的具体地址信息
-
直接指针
使用直接指针访问,那么Java堆对象的布局中就必须考虑如何放置访问类型数据的相关信息,而reference中存储的直接就是对象地址
java IDL、RMI-IIOP
部署工具 3.2 JVisualVM && GraalvmGraalvm-ce-java8-21.2.0
相当于把JDK中基本的排障工具进行组合,更加方便的一个可视化工具
跟Jconsole差不多,但是它可以引入插件
3.3 JProfiler贵死了,正版授权499美元
四、字节码文件与类加载描述类文件结构/类加载
4.1 Class类文件结构-
魔数
每个Class头4个字节被称为魔数,用来确定这个文件是不是能被JVM虚拟机接受的类文件
例如这个文件存储的版本号魔数是B,但是JVM只能执行A版本的Class文件
-
常量池
字面量 and 符号引用
-
访问标志
说明这类的信息,例如:是否是public,是否是接口,是否是final
-
索引、属性、方法、字段等
通过将指令放在虚拟机操作数栈,指令执行进行入栈和出栈
4.3 类的生命周期 4.4 类的加载过程 加载- 通过类的全限定名来获取定义这个类的二进制流
- 把字节流静态存储结构,转换为,方法区数据结构,通过类加载器加载到方法区中
- 在内存生成这个类的Class对象,作为方法区这个类的各种数据访问入口
连接阶段的第一步,验证字节流中的信息是否符合规范
准备为类中定义的变量(静态变量)分配内存,这些变量所使用的内存都在方法区进行分配
解析JVM将常量池内的符号引用替换为直接引用的过程
直接引用的实现跟虚拟机的内存布局相关,直接引用是可以直接指向目标的指针
初始化 4.5 类加载器public abstract class ClassLoader
类加载器直接决定了比较两个类是否“相等”,由不同类加载器加载的类是必然不相等的
例如通过应用类加载器和自定义类加载器加载同一个类,equal()方法出来都不会相同
4.6 破坏双亲委派模型&&线程上下文类加载器双亲委派模型的工作过程
- 如果一个类加载器收到了类加载请求,它首先不会自己去加载,而是抛给父类加载器,层层往上抛,跑到老祖宗加载器
- 类加载是通过类的全限定名进行加载的,如果父类加载器在它搜索范围内没有这个类,就从上往下抛给儿子加载
- 这么做的好处是,有一个优先级的层次关系,并且如果过多的类加载器加载的类不会显得混乱
- 类加载请求的前提是,会先判断这个类有没有被加载过
1
4.7 Java模块化系统1
五、字节码执行引擎1
5.1 运行时栈帧的结构1
5.2 方法调用1
5.3 动态语言类型支持1
5.4 基于栈/基于寄存器的指令集1
六、前端编译优化1
七、后端编译优化1
太难了我擦,先跳过回头补
over


