Skip to content

Commit

Permalink
深入理解Java虚拟机
Browse files Browse the repository at this point in the history
  • Loading branch information
geekyspace committed Aug 8, 2024
1 parent 8406c02 commit e59d62c
Show file tree
Hide file tree
Showing 8 changed files with 172 additions and 53 deletions.
2 changes: 1 addition & 1 deletion src/.vuepress/path/navbar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default navbar([
},
{
text: "Java进阶-JVM相关", children:[
{text: "深入理解Java虚拟机", icon: "jvm-xx", link: "md/jvm/overview"},
{text: "深入理解Java虚拟机", icon: "jvm-xx", link: "md/jvm/"},
],
},
]
Expand Down
31 changes: 25 additions & 6 deletions src/.vuepress/path/sidebar/jvm.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,34 @@
import {arraySidebar} from "vuepress-theme-hope";

export const jvm = arraySidebar([
{text: "概述", link: "overview"},
{text: "总目录", prefix: "/md/jvm/", link: "/md/jvm/",},
{
text: "JVM规范", collapsible: true, prefix: "specs/", link: "specs/",
text: "走近Java", prefix: "part1/", link: "part1/",
children: [
{text: "类文件结构", link: "class"},
{text: "字节码指令集", link: "bytecode"},
{text: "JVM概述", link: "overview"},
{text: "编译JDK", link: "compile_jdk"},
],
},
{text: "类加载机制", link: "classload"},
{text: "实战编译JDK", link: "compile_jdk"},
{
text: "自动内存管理", prefix: "part2/", link: "part2/",
children: [],
},
{
text: "虚拟机执行子系统", prefix: "part3/", link: "part3/",
children: [
{text: "类文件结构", link: "class-file-structure"},
{text: "字节码指令集", link: "bytecode-instructions-set"},
{text: "类加载机制", link: "class-loading-mechanism"},
],
},
{
text: "程序编译与代码优化", prefix: "part4/", link: "part4/",
children: [],
},
{
text: "高效并发", prefix: "part5/", link: "part5/",
children: [],
},

]
);
124 changes: 124 additions & 0 deletions src/md/jvm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
---
title: 深入理解Java虚拟机(持续连载)
description:
author: 会敲代码的程序猿
isOriginal: true
date: 2024-08-08
category: JVM
tag: JVM
---

# 深入理解Java虚拟机目录(持续连载)

## 前言(Preface)

## 致谢(Acknowledgements)

## 第一部分 走近Java(Part 1: Approaching Java)

- **第1章 走近Java(Chapter 1: Approaching Java)**
- 1.1 概述(Overview)
- 1.2 Java技术体系(Java Technology System)
- 1.3 Java发展史(History of Java)
- [1.4 Java虚拟机家族(Java Virtual Machine Family)](part1/overview.html#java虚拟机家族)
- 1.5 展望Java技术的未来(Future of Java Technology)
- [1.6 实战:自己编译JDK(Practical: Compiling JDK)](part1/compile_jdk)

## 第二部分 自动内存管理(Part 2: Automatic Memory Management)

- **第2章 Java内存区域与内存溢出异常(Chapter 2: Java Memory Areas and OutOfMemoryError)**
- 2.1 概述(Overview)
- 2.2 程序计数器(Program Counter Register)
- 2.3 Java虚拟机栈(Java Virtual Machine Stacks)
- 2.4 本地方法栈(Native Method Stacks)
- 2.5 堆(Heap)
- 2.6 方法区(Method Area)
- 2.7 运行时常量池(Runtime Constant Pool)
- 2.8 直接内存(Direct Memory)

- **第3章 垃圾收集器与内存分配策略(Chapter 3: Garbage Collectors and Memory Allocation Strategies)**
- 3.1 概述(Overview)
- 3.2 对象已死吗?(Is the Object Dead?)
- 3.3 垃圾收集算法(Garbage Collection Algorithms)
- 3.4 HotSpot的算法实现(HotSpot Algorithm Implementation)
- 3.5 垃圾收集器(Garbage Collectors)

- **第4章 虚拟机性能监控、故障处理工具(Chapter 4: JVM Performance Monitoring and Troubleshooting Tools)**
- 4.1 概述(Overview)
- 4.2 JConsole介绍(Introduction to JConsole)
- 4.3 VisualVM介绍(Introduction to VisualVM)
- 4.4 其他工具(Other Tools)

- **第5章 调优案例分析与实战(Chapter 5: Optimization Case Analysis and Practices)**
- 5.1 概述(Overview)
- 5.2 实战案例分析(Practical Case Analysis)
- 5.3 调优实践(Optimization Practices)

## 第三部分 虚拟机执行子系统(Part 3: JVM Execution Subsystem)

- **第6章 类文件结构(Chapter 6: Class File Structure)**
- 6.1 概述(Overview)
- [6.2 无关性的基石(The Cornerstone of Independence)](part3/class-file-structure.html#跨平台的基石)
- [6.3 Class类文件的结构(Structure of Class File)](part3/class-file-structure.html#class类文件结构-理论)
- [6.4 字节码指令简介(Introduction to Bytecode Instructions)](part3/bytecode-instructions-set)
- 6.5 公有设计,私有实现(Public Design, Private Implementation)
- 6.6 Class文件结构的发展(Development of Class File Structure)

- **第7章 虚拟机类加载机制(Chapter 7: JVM Class Loading Mechanism)**
- 7.1 概述(Overview)
- 7.2 类加载的时机(Timing of Class Loading)
- [7.3 类加载的过程(Class Loading Process)](part3/class-loading-mechanism.html#类加载的过程)
- 7.4 类加载器(Class Loaders)
- 7.5 Java模块化系统(Java Modular System)

- **第8章 虚拟机字节码执行引擎(Chapter 8: JVM Bytecode Execution Engine)**
- 8.1 概述(Overview)
- 8.2 运行时栈帧结构(Runtime Stack Frame Structure)
- 8.3 方法调用与返回(Method Invocation and Return)

- **第9章 类加载及执行子系统的案例与实战(Chapter 9: Case Studies and Practices of Class Loading and Execution Subsystem)
**
- 9.1 概述(Overview)
- 9.2 实战案例分析(Practical Case Analysis)
- 9.3 调优实践(Optimization Practices)

## 第四部分 程序编译与代码优化(Part 4: Program Compilation and Code Optimization)

- **第10章 前端编译与优化(Chapter 10: Front-end Compilation and Optimization)**
- 10.1 概述(Overview)
- 10.2 语法与语义分析(Syntax and Semantic Analysis)
- 10.3 字节码生成(Bytecode Generation)

- **第11章 后端编译与优化(Chapter 11: Back-end Compilation and Optimization)**
- 11.1 概述(Overview)
- 11.2 即时编译器(Just-in-time Compiler)
- 11.3 编译优化(Compilation Optimization)

## 第五部分 高效并发(Part 5: Efficient Concurrency)

- **第12章 Java内存模型与线程(Chapter 12: Java Memory Model and Threads)**
- 12.1 概述(Overview)
- 12.2 Java内存模型(Java Memory Model)
- 12.3 线程与线程池(Threads and Thread Pools)

- **第13章 线程安全与锁优化(Chapter 13: Thread Safety and Lock Optimization)**
- 13.1 概述(Overview)
- 13.2 线程安全(Thread Safety)
- 13.3 锁优化(Lock Optimization)

## 附录(Appendices)

- **附录A 在Windows系统下编译OpenJDK 6(Appendix A: Compiling OpenJDK 6 on Windows)**
- **附录B 展望Java技术的未来(2013年版)(Appendix B: Outlook of Java Technology's Future (2013 Edition))**
- **附录C 虚拟机字节码指令表(Appendix C: JVM Bytecode Instruction Table)**
- C.1 指令集概述(Overview of Instruction Set)
- C.2 常用指令详解(Detailed Explanation of Common Instructions)

- **附录D 对象查询语言(OQL)简介(Appendix D: Introduction to Object Query Language (OQL))**
- D.1 概述(Overview)
- D.2 OQL语法(OQL Syntax)
- D.3 使用案例(Usage Cases)

- **附录E JDK历史版本轨迹(Appendix E: Historical Versions of the JDK)**
- E.1 概述(Overview)
- E.2 版本列表(Version List)
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ isOriginal: true
date: 2024-07-26
category: JVM
tag: JVM
order: 1
---

# 实战编译JDK
Expand Down
1 change: 0 additions & 1 deletion src/md/jvm/overview.md → src/md/jvm/part1/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ isOriginal: true
date: 2024-07-19
category: JVM
tag: JVM
order: 1
---

# Java虚拟机概述
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ isOriginal: true
date: 2024-07-26
category: JVM
tag: JVM
order: 2
---

# 字节码指令集
Expand All @@ -18,37 +17,7 @@ order: 2

由于JVM采用面向操作数栈而不是面向寄存器的架构,大多数指令都不包含操作数,只有一个操作码,指令参数存放在操作数栈中。

**优势和劣势**

限制Java虚拟机操作码的长度为一个字节(即0~255),意味着指令集的操作码总数不能超过256条;
Class文件格式放弃了编译后代码的操作数长度对齐,需要在运行时从字节中重建具体数据结构。
例如,存储16位无符号整数要使用两个无符号字节(`byte1``byte2`):


```shell
(byte1 << 8) | byte2
```
这种操作可能导致解释执行字节码时性能损失,但省略了大量的填充和间隔符号,用一个字节代表操作码,使编译代码更小,更适合高传输效率的设计。
Java语言设计初期主要面向网络和智能家电,这种设计一直沿用至今。
**执行模型**
如果不考虑异常处理的话,那Java虚拟机的解释器可以使用下面这段伪代码作为最基本的执行模型来理解:
```java
do {
自动计算PC寄存器的值加1;
根据PC寄存器指示的位置,从字节码流中取出操作码;
if (字节码存在操作数) 从字节码流中取出操作数;
执行操作码所定义的操作;
} while (字节码流长度 > 0);
```
字节码指令流基本上都是单字节对齐的,只有“tableswitch”和“lookupswitch”两条指令例外,
由于操作数特殊,是以4字节为界划分的,所以需要预留出相应的空位填充来实现对齐。
## 字节码与数据类型
## 操作码助记符

数据类型相关的字节码指令,包含特定的**操作码助记符**

Expand All @@ -73,10 +42,13 @@ if (字节码存在操作数) 从字节码流中取出操作数;
由于操作码长度只有一个字节,如果每种类型的指令都支持所有数据类型,指令数量将超出范围。
因此,Java虚拟机的指令集设计成非完全独立的(“Not Orthogonal”)。
即并非每种数据类型和每一种操作都有对应的指令。
参考下表**Java虚拟机指令集所支持的数据类型**

## 操作码表

使用数据类型对应的操作码助记符替换操作码`opcode`列指令模板中的`T`,得到具体的字节码指令。

参考下表**Java虚拟机指令集所支持的数据类型**

| opcode | byte | short | int | long | float | double | char | reference |
|---------------|--------|---------|-----------|---------|---------|---------|---------|-----------|
| **Tpush** | bipush | sipush | | | | | | |
Expand Down Expand Up @@ -116,7 +88,9 @@ if (字节码存在操作数) 从字节码流中取出操作数;

因此,大多数对`boolean``byte``short``char`类型数据的操作,实际上都是使用`int`类型进行的。

## 加载和存储指令
## 字节码指令分类

### 加载和存储指令

> 加载和存储指令用于在栈帧中的局部变量表和操作数栈之间传输数据。
Expand Down Expand Up @@ -147,7 +121,7 @@ if (字节码存在操作数) 从字节码流中取出操作数;
加载和存储指令主要用于操作数栈和局部变量表之间的数据传输。
此外,一些指令(如访问对象字段或数组元素的指令)也会涉及操作数栈的数据传输。

## 运算指令
### 运算指令

> 算术指令用于对两个操作数栈上的值进行特定运算,并将结果重新存入到操作栈顶。
Expand All @@ -165,7 +139,7 @@ if (字节码存在操作数) 从字节码流中取出操作数;
* 局部变量自增指令:`iinc`
* 比较指令:`dcmpg``dcmpl``fcmpg``fcmpl``lcmp`

## 类型转换指令
### 类型转换指令

> 类型转换指令可以将两种不同的数值类型相互转换。
> 用于实现用户代码中的显式类型转换操作,或处理字节码指令集中数据类型相关指令无法与数据类型一一对应的问题。
Expand All @@ -177,7 +151,7 @@ if (字节码存在操作数) 从字节码流中取出操作数;
- **窄化类型转换:** 与“宽化”相对,需显式指令,可能导致正负号变化和精度丢失
* `i2b``i2c``i2s``l2i``f2i``f2l``d2i``d2l``d2f`

## 对象创建与访问指令
### 对象创建与访问指令

虽然类实例和数组都是对象,但Java虚拟机对类实例和数组的创建与操作使用了不同的字节码指令。
对象创建后,可以通过对象访问指令来获取对象实例或数组中的字段或者数组元素。
Expand All @@ -192,7 +166,7 @@ if (字节码存在操作数) 从字节码流中取出操作数;
* 数组操作:`arraylength`
* 类型检查和转换:`instanceof``checkcast`

## 操作数栈管理指令
### 操作数栈管理指令

如同操作一个普通数据结构中的堆栈那样,Java虚拟机提供了一些用于直接操作操作数栈的指令,包括:

Expand All @@ -201,7 +175,7 @@ if (字节码存在操作数) 从字节码流中取出操作数;
* 复制栈顶元素:`dup``dup2``dup_x1``dup2_x1``dup_x2``dup2_x2`
* 互换栈顶两个元素:`swap`

## 控制转移指令
### 控制转移指令

> 控制转移指令用于在程序执行过程中有条件或无条件地跳转到其他指令位置,修改程序计数器(PC)的值。
Expand All @@ -223,7 +197,7 @@ if (字节码存在操作数) 从字节码流中取出操作数;
* `boolean``byte``char``short`直接使用`int`类型指令
* `long``float``double`先用对应比较指令,再转换为`int`进行条件分支

## 方法调用和返回指令
### 方法调用和返回指令

- **方法调用(分派、执行过程)** 分为以下五种指令,用于不同类型的方法调用:
* `invokevirtual`:调用对象的实例方法,依据对象的实际类型进行分派(虚方法分派),最常见
Expand All @@ -239,7 +213,7 @@ if (字节码存在操作数) 从字节码流中取出操作数;
* `areturn`:返回引用类型的值
* `return`:用于声明为 `void` 的方法、实例初始化方法、类初始化方法

## 异常处理指令
### 异常处理指令

在Java程序中,**显式抛出异常**`throw` 语句)由`athrow`指令实现。

Expand All @@ -248,7 +222,7 @@ if (字节码存在操作数) 从字节码流中取出操作数;

处理异常(`catch` 语句)在Java虚拟机中不是通过字节码指令实现的,而是采用**异常表**来完成。

## 同步指令
### 同步指令

Java虚拟机支持方法级的同步和方法内部一段指令序列的同步,这两种同步结构都是使用**管程**(Monitor,通常称为“锁”)来实现的。

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ isOriginal: true
date: 2024-07-19
category: JVM
tag: JVM
order: 1
---

# 类文件结构
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ isOriginal: true
date: 2024-07-20
category: JVM
tag: JVM
order: 3
---

# 类加载机制
Expand Down Expand Up @@ -111,4 +110,10 @@ Java类加载过程主要分为加载、连接(验证、准备、解析)、

## 类加载器

> 加载阶段“通过一个类的全限定名来获取描述该类的二进制字节流”,这个动作的代码被称为“类加载器”(Class Loader)。
### 类与类加载器

### 双亲委派模型

### 破坏双亲委派模型

0 comments on commit e59d62c

Please sign in to comment.