Skip to content

Commit eb967d7

Browse files
committed
docs: improve readability
1 parent 4e2206b commit eb967d7

5 files changed

+15
-15
lines changed

docs/01-jvm-memory-structure.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ Java 虚拟机栈的栈顶的栈帧是当前正在执行的活动栈,也就是
9191
- 线程共享,整个 Java 虚拟机只有一个堆,所有的线程都访问同一个堆。而程序计数器、Java 虚拟机栈、本地方法栈都是一个线程对应一个。
9292
- 在虚拟机启动时创建。
9393
- 是垃圾回收的主要场所。
94-
- 进一步可分为:新生代\(Eden 区 From Survior To Survivor\)、老年代。
94+
- 进一步可分为:新生代Eden 区`From Survior``To Survivor`、老年代。
9595

9696
不同的区域存放不同生命周期的对象,这样可以根据不同的区域使用不同的垃圾回收算法,更具有针对性。
9797

@@ -121,7 +121,7 @@ Java 虚拟机规范中定义方法区是堆的一个逻辑部分。方法区存
121121

122122
方法区中存放:类信息、常量、静态变量、即时编译器编译后的代码。常量就存放在运行时常量池中。
123123

124-
当类被 Java 虚拟机加载后, .class 文件中的常量就存放在方法区的运行时常量池中。而且在运行期间,可以向常量池中添加新的常量。如 String 类的 intern\(\) 方法就能在运行期间向常量池中添加字符串常量。
124+
当类被 Java 虚拟机加载后, .class 文件中的常量就存放在方法区的运行时常量池中。而且在运行期间,可以向常量池中添加新的常量。如 String 类的 `intern()` 方法就能在运行期间向常量池中添加字符串常量。
125125

126126
## 直接内存(堆外内存)
127127

docs/06-jvm-performance-tuning.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,4 @@
4545

4646
直接内存虽然不是 JVM 内存空间,但它的垃圾回收也由 JVM 负责。
4747

48-
垃圾收集进行时,虚拟机虽然会对直接内存进行回收, 但是直接内存却不能像新生代、老年代那样,发现空间不足了就通知收集器进行垃圾回收, 它只能等老年代满了后 Full GC,然后“顺便”帮它清理掉内存的废弃对象。 否则只能一直等到抛出内存溢出异常时,先 catch 掉,再在 catch 块里大喊 “System.gc\(\)”。 要是虚拟机还是不听,那就只能眼睁睁看着堆中还有许多空闲内存,自己却不得不抛出内存溢出异常了。
48+
垃圾收集进行时,虚拟机虽然会对直接内存进行回收, 但是直接内存却不能像新生代、老年代那样,发现空间不足了就通知收集器进行垃圾回收, 它只能等老年代满了后 Full GC,然后“顺便”帮它清理掉内存的废弃对象。 否则只能一直等到抛出内存溢出异常时,先 catch 掉,再在 catch 块里大喊 “`System.gc()`”。 要是虚拟机还是不听,那就只能眼睁睁看着堆中还有许多空闲内存,自己却不得不抛出内存溢出异常了。

docs/08-load-class-time.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Java 虚拟机规范没有强制约束类加载过程的第一阶段(即:加
2525
- 在遇到 new、putstatic、getstatic、invokestatic 字节码指令时,如果类尚未初始化,则需要先触发其初始化。
2626
- 对类进行反射调用时,如果类还没有初始化,则需要先触发其初始化。
2727
- 初始化一个类时,如果其父类还没有初始化,则需要先初始化父类。
28-
- 虚拟机启动时,用于需要指定一个包含 main\(\) 方法的主类,虚拟机会先初始化这个主类。
28+
- 虚拟机启动时,用于需要指定一个包含 `main()` 方法的主类,虚拟机会先初始化这个主类。
2929
- 当使用 JDK 1.7 的动态语言支持时,如果一个 java.lang.invoke.MethodHandle 实例最后的解析结果为 REF_getStatic、REF_putStatic、REF_invokeStatic 的方法句柄,并且这个方法句柄所对应的类还没初始化,则需要先触发其初始化。
3030

3131
这 5 种场景中的行为称为对一个类进行**主动引用**,除此之外,其它所有引用类的方式都不会触发初始化,称为**被动引用**

docs/09-load-class-process.md

+8-8
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
### “非数组类”与“数组类”加载比较
2626

27-
- 非数组类加载阶段可以使用系统提供的引导类加载器,也可以由用户自定义的类加载器完成,开发人员可以通过定义自己的类加载器控制字节流的获取方式(如重写一个类加载器的 loadClass\(\) 方法)
27+
- 非数组类加载阶段可以使用系统提供的引导类加载器,也可以由用户自定义的类加载器完成,开发人员可以通过定义自己的类加载器控制字节流的获取方式(如重写一个类加载器的 `loadClass()` 方法)
2828
- 数组类本身不通过类加载器创建,它是由 Java 虚拟机直接创建的,再由类加载器创建数组中的元素类。
2929

3030
### 注意事项
@@ -77,9 +77,9 @@ public static final int value = 123;
7777

7878
## 初始化
7979

80-
类初始化阶段是类加载过程的最后一步,是执行类构造器 <clinit>\(\) 方法的过程。
80+
类初始化阶段是类加载过程的最后一步,是执行类构造器 `<clinit>()` 方法的过程。
8181

82-
&lt;clinit&gt;\(\) 方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块(static {} 块)中的语句合并产生的,编译器收集的顺序是由语句在源文件中出现的顺序所决定的。
82+
`<clinit>()` 方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块(static {} 块)中的语句合并产生的,编译器收集的顺序是由语句在源文件中出现的顺序所决定的。
8383

8484
静态语句块中只能访问定义在静态语句块之前的变量,定义在它之后的变量,在前面的静态语句块中可以赋值,但不能访问。如下方代码所示:
8585

@@ -93,9 +93,9 @@ public class Test {
9393
}
9494
```
9595

96-
&lt;clinit&gt;\(\) 方法不需要显式调用父类构造器,虚拟机会保证在子类的 &lt;clinit&gt;\(\) 方法执行之前,父类的 &lt;clinit&gt;\(\) 方法已经执行完毕。
96+
`<clinit>()` 方法不需要显式调用父类构造器,虚拟机会保证在子类的 `<clinit>()` 方法执行之前,父类的 `<clinit>()` 方法已经执行完毕。
9797

98-
由于父类的 &lt;clinit&gt;\(\) 方法先执行,意味着父类中定义的静态语句块要优先于子类的变量赋值操作。如下方代码所示:
98+
由于父类的 `<clinit>()` 方法先执行,意味着父类中定义的静态语句块要优先于子类的变量赋值操作。如下方代码所示:
9999

100100
```java
101101
static class Parent {
@@ -114,8 +114,8 @@ public static void main(String[] args) {
114114
}
115115
```
116116

117-
&lt;clinit&gt;\(\) 方法不是必需的,如果一个类没有静态语句块,也没有对类变量的赋值操作,那么编译器可以不为这个类生成 &lt;clinit&gt;\(\) 方法。
117+
`<clinit>()` 方法不是必需的,如果一个类没有静态语句块,也没有对类变量的赋值操作,那么编译器可以不为这个类生成 `<clinit>()` 方法。
118118

119-
接口中不能使用静态代码块,但接口也需要通过 &lt;clinit&gt;\(\) 方法为接口中定义的静态成员变量显式初始化。但接口与类不同,接口的 &lt;clinit&gt;\(\) 方法不需要先执行父类的 &lt;clinit&gt;\(\) 方法,只有当父接口中定义的变量使用时,父接口才会初始化。
119+
接口中不能使用静态代码块,但接口也需要通过 `<clinit>()` 方法为接口中定义的静态成员变量显式初始化。但接口与类不同,接口的 `<clinit>()` 方法不需要先执行父类的 `<clinit>()` 方法,只有当父接口中定义的变量使用时,父接口才会初始化。
120120

121-
虚拟机会保证一个类的 &lt;clinit&gt;\(\) 方法在多线程环境中被正确加锁、同步。如果多个线程同时去初始化一个类,那么只会有一个线程去执行这个类的 &lt;clinit&gt;\(\) 方法。
121+
虚拟机会保证一个类的 `<clinit>()` 方法在多线程环境中被正确加锁、同步。如果多个线程同时去初始化一个类,那么只会有一个线程去执行这个类的 `<clinit>()` 方法。

docs/10-class-loader.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@
88

99
因此,比较两个类是否“相等”,只有在这两个类是由同一个类加载器加载的前提下才有意义,否则,即使这两个类来源于同一个 Class 文件,被同一个虚拟机加载,只要加载它们的类加载器不同,那么这两个类就必定不相等。
1010

11-
这里的“相等”,包括代表类的 Class 对象的 equals\(\) 方法、isInstance\(\) 方法的返回结果,也包括使用 instanceof 关键字做对象所属关系判定等情况。
11+
这里的“相等”,包括代表类的 Class 对象的 `equals()` 方法、`isInstance()` 方法的返回结果,也包括使用 instanceof 关键字做对象所属关系判定等情况。
1212

1313
### 加载器种类
1414

1515
系统提供了 3 种类加载器:
1616

1717
- 启动类加载器(Bootstrap ClassLoader): 负责将存放在 `<JAVA_HOME>\lib` 目录中的,并且能被虚拟机识别的(仅按照文件名识别,如 rt.jar,名字不符合的类库即使放在 lib 目录中也不会被加载)类库加载到虚拟机内存中。
1818
- 扩展类加载器(Extension ClassLoader): 负责加载 `<JAVA_HOME>\lib\ext` 目录中的所有类库,开发者可以直接使用扩展类加载器。
19-
- 应用程序类加载器(Application ClassLoader): 由于这个类加载器是 ClassLoader 中的 getSystemClassLoader\(\) 方法的返回值,所以一般也称它为“系统类加载器”。它负责加载用户类路径(classpath)上所指定的类库,开发者可以直接使用这个类加载器,如果应用程序中没有自定义过自己的类加载器,一般情况下这个就是程序中默认的类加载器。
19+
- 应用程序类加载器(Application ClassLoader): 由于这个类加载器是 ClassLoader 中的 `getSystemClassLoader()` 方法的返回值,所以一般也称它为“系统类加载器”。它负责加载用户类路径(classpath)上所指定的类库,开发者可以直接使用这个类加载器,如果应用程序中没有自定义过自己的类加载器,一般情况下这个就是程序中默认的类加载器。
2020

2121
![ClassLoader](./images/classloader.png)
2222

@@ -32,7 +32,7 @@
3232

3333
如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请求(找不到所需的类)时,子加载器才会尝试自己去加载。
3434

35-
在 java.lang.ClassLoader 中的 loadClass\(\) 方法中实现该过程。
35+
在 java.lang.ClassLoader 中的 `loadClass` 方法中实现该过程。
3636

3737
### 为什么使用双亲委派模型
3838

0 commit comments

Comments
 (0)