diff --git a/notes/Java 虚拟机.md b/notes/Java 虚拟机.md
index 48714c97..965e6027 100644
--- a/notes/Java 虚拟机.md
+++ b/notes/Java 虚拟机.md
@@ -12,7 +12,6 @@
* [垃圾收集算法](#垃圾收集算法)
* [垃圾收集器](#垃圾收集器)
* [内存分配与回收策略](#内存分配与回收策略)
- * [Full GC 的触发条件](#full-gc-的触发条件)
* [三、类加载机制](#三类加载机制)
* [类的生命周期](#类的生命周期)
* [类初始化时机](#类初始化时机)
@@ -47,8 +46,8 @@ java -Xss=512M HackTheJava
该区域可能抛出以下异常:
-1. 当线程请求的栈深度超过最大值,会抛出 StackOverflowError 异常;
-2. 栈进行动态扩展时如果无法申请到足够内存,会抛出 OutOfMemoryError 异常。
+- 当线程请求的栈深度超过最大值,会抛出 StackOverflowError 异常;
+- 栈进行动态扩展时如果无法申请到足够内存,会抛出 OutOfMemoryError 异常。
## 本地方法栈
@@ -90,7 +89,9 @@ java -Xms=1M -Xmx=2M HackTheJava
和 Java 堆一样不需要连续的内存,并且可以动态扩展,动态扩展失败一样会抛出 OutOfMemoryError 异常。
-对这块区域进行垃圾回收的主要目标是对常量池的回收和对类的卸载,但是一般比较难实现。JDK1.7 之前,HotSpot 虚拟机把它当成永久代来进行垃圾回收,JDK8 之后,取消了永久代,用 metaspace(元数据)区替代。
+对这块区域进行垃圾回收的主要目标是对常量池的回收和对类的卸载,但是一般比较难实现。
+
+JDK 1.7 之前,HotSpot 虚拟机把它当成永久代来进行垃圾回收,JDK 1.8 之后,取消了永久代,用 metaspace(元数据)区替代。
## 运行时常量池
@@ -110,39 +111,49 @@ Class 文件中的常量池(编译器生成的各种字面量和符号引用
## 判断一个对象是否可回收
-### 1. 引用计数
+### 1. 引用计数算法
给对象添加一个引用计数器,当对象增加一个引用时计数器加 1,引用失效时计数器减 1。引用计数为 0 的对象可被回收。
两个对象出现循环引用的情况下,此时引用计数器永远不为 0,导致无法对它们进行回收。
```java
-objA.instance = objB;
-objB.instance = objA;
+public class ReferenceCountingGC {
+ public Object instance = null;
+
+ public static void main(String[] args) {
+ ReferenceCountingGC objectA = new ReferenceCountingGC();
+ ReferenceCountingGC objectB = new ReferenceCountingGC();
+ objectA.instance = objectB;
+ objectB.instance = objectA;
+ }
+}
```
-### 2. 可达性
+正因为循环引用的存在,因此 Java 虚拟机不适用引用计数算法。
-通过 GC Roots 作为起始点进行搜索,能够到达到的对象都是可用的,不可达的对象可被回收。
+### 2. 可达性分析算法
+
+通过 GC Roots 作为起始点进行搜索,能够到达到的对象都是存活的,不可达的对象可被回收。
-GC Roots 一般包含以下内容:
+Java 虚拟机使用该算法来判断对象是否可被回收,在 Java 中 GC Roots 一般包含以下内容:
-1. 虚拟机栈中引用的对象
-2. 方法区中类静态属性引用的对象
-3. 方法区中的常量引用的对象
-4. 本地方法栈中引用的对象
+- 虚拟机栈中引用的对象
+- 本地方法栈中引用的对象
+- 方法区中类静态属性引用的对象
+- 方法区中的常量引用的对象
### 3. 引用类型
-无论是通过引用计算算法判断对象的引用数量,还是通过可达性分析算法判断对象的引用链是否可达,判定对象是否存活都与引用有关。
+无论是通过引用计算算法判断对象的引用数量,还是通过可达性分析算法判断对象的引用链是否可达,判定对象是否可被回收都与引用有关。
-Java 对引用的概念进行了扩充,引入四种强度不同的引用类型。
+Java 具有四种强度不同的引用类型。
**(一)强引用**
-只要强引用存在,垃圾回收器永远不会回收被引用的对象。
+被强引用关联的对象不会被垃圾收集器回收。
使用 new 一个新对象的方式来创建强引用。
@@ -152,28 +163,69 @@ Object obj = new Object();
**(二)软引用**
-用来描述一些还有用但是并非必需的对象。
+被软引用关联的对象,只有在内存不够的情况下才会被回收。
-在系统将要发生内存溢出异常之前,会将这些对象列进回收范围之中进行第二次回收。
-
-软引用主要用来实现类似缓存的功能,在内存足够的情况下直接通过软引用取值,无需从繁忙的真实来源获取数据,提升速度;当内存不足时,自动删除这部分缓存数据,从真正的来源获取这些数据。
-
-使用 SoftReference 类来实现软引用。
+使用 SoftReference 类来创建软引用。
```java
Object obj = new Object();
SoftReference