diff --git a/notes/Java 虚拟机.md b/notes/Java 虚拟机.md index acb244a7..dd058ee9 100644 --- a/notes/Java 虚拟机.md +++ b/notes/Java 虚拟机.md @@ -8,7 +8,7 @@ * [运行时常量池](#运行时常量池) * [直接内存](#直接内存) * [二、垃圾收集](#二垃圾收集) - * [判断一个对象是否可回收](#判断一个对象是否可回收) + * [判断一个对象是否存活](#判断一个对象是否存活) * [垃圾收集算法](#垃圾收集算法) * [垃圾收集器](#垃圾收集器) * [内存分配与回收策略](#内存分配与回收策略) @@ -61,16 +61,18 @@ java -Xss=512M HackTheJava 所有对象实例都在这里分配内存。 -是垃圾收集的主要区域("GC 堆"),现代的垃圾收集器基本都是采用分代收集算法,该算法的思想是针对不同的对象采取不同的垃圾回收算法,因此虚拟机把 Java 堆分成以下三块: +是垃圾收集的主要区域("GC 堆")。现代的垃圾收集器基本都是采用分代收集算法,主要思想是针对不同的对象采取不同的垃圾回收算法。虚拟机把 Java 堆分成以下三块: - 新生代(Young Generation) - 老年代(Old Generation) - 永久代(Permanent Generation) -当一个对象被创建时,它首先进入新生代,之后有可能被转移到老年代中。新生代存放着大量的生命很短的对象,因此新生代在三个区域中垃圾回收的频率最高。为了更高效地进行垃圾回收,把新生代继续划分成以下三个空间: +当一个对象被创建时,它首先进入新生代,之后有可能被转移到老年代中。 -- Eden -- From Survivor +新生代存放着大量的生命很短的对象,因此新生代在三个区域中垃圾回收的频率最高。为了更高效地进行垃圾回收,把新生代继续划分成以下三个空间: + +- Eden(伊甸园) +- From Survivor(幸存者) - To Survivor

@@ -99,7 +101,7 @@ JDK 1.7 之前,HotSpot 虚拟机把它当成永久代来进行垃圾回收,J Class 文件中的常量池(编译器生成的各种字面量和符号引用)会在类加载后被放入这个区域。 -除了在编译期生成的常量,还允许动态生成,例如 String 类的 intern()。这部分常量也会被放入运行时常量池。 +除了在编译期生成的常量,还允许动态生成,例如 String 类的 intern()。 ## 直接内存 @@ -109,11 +111,11 @@ Class 文件中的常量池(编译器生成的各种字面量和符号引用 程序计数器、虚拟机栈和本地方法栈这三个区域属于线程私有的,只存在于线程的生命周期内,线程结束之后也会消失,因此不需要对这三个区域进行垃圾回收。垃圾回收主要是针对 Java 堆和方法区进行。 -## 判断一个对象是否可回收 +## 判断一个对象是否存活 ### 1. 引用计数算法 -给对象添加一个引用计数器,当对象增加一个引用时计数器加 1,引用失效时计数器减 1。引用计数为 0 的对象可被回收。 +给对象添加一个引用计数器,当对象增加一个引用时计数器加 1,引用失效时计数器减 1。引用计数不为 0 的对象仍然存活。 两个对象出现循环引用的情况下,此时引用计数器永远不为 0,导致无法对它们进行回收。 @@ -147,7 +149,7 @@ Java 虚拟机使用该算法来判断对象是否可被回收,在 Java 中 GC ### 3. 引用类型 -无论是通过引用计算算法判断对象的引用数量,还是通过可达性分析算法判断对象的引用链是否可达,判定对象是否可被回收都与引用有关。 +无论是通过引用计算算法判断对象的引用数量,还是通过可达性分析算法判断对象是否可达,判定对象是否可被回收都与引用有关。 Java 具有四种强度不同的引用类型。 @@ -170,7 +172,7 @@ Object obj = new Object(); ```java Object obj = new Object(); SoftReference sf = new SoftReference(obj); -obj = null; // 使对象只被软引用关联 +obj = null; // 使对象只被软引用关联 ``` **(三)弱引用** @@ -270,7 +272,7 @@ finalize() 类似 C++ 的析构函数,用来做关闭外部资源等工作。

-将需要存活的对象进行标记,然后清理掉未被标记的对象。 +将存活的对象进行标记,然后清理掉未被标记的对象。 不足: @@ -308,11 +310,14 @@ finalize() 类似 C++ 的析构函数,用来做关闭外部资源等工作。 以上是 HotSpot 虚拟机中的 7 个垃圾收集器,连线表示垃圾收集器可以配合使用。 +- 单线程与并行(多线程):单线程指的是垃圾收集器只使用一个线程进行收集,而并行使用多个线程。 +- 串行与并发:串行指的是垃圾收集器与用户程序交替执行,这意味着在执行垃圾收集的时候需要停顿用户程序;并发指的是垃圾收集器和用户程序同时执行。除了 CMS 和 G1 之外,其它垃圾收集器都是以串行的方式执行。 + ### 1. Serial 收集器

-Serial 翻译为串行,垃圾收集和用户程序不能同时执行,这意味着在执行垃圾收集的时候需要停顿用户程序。除了 CMS 和 G1 之外,其它收集器都是以串行的方式执行。CMS 和 G1 可以使得垃圾收集和用户程序同时执行,被称为并发执行。 +Serial 翻译为串行,也就是说它以串行的方式执行。 它是单线程的收集器,只会使用一个线程进行垃圾收集工作。 @@ -328,7 +333,7 @@ Serial 翻译为串行,垃圾收集和用户程序不能同时执行,这意 是 Server 模式下的虚拟机首选新生代收集器,除了性能原因外,主要是因为除了 Serial 收集器,只有它能与 CMS 收集器配合工作。 -默认开始的线程数量与 CPU 数量相同,可以使用 -XX:ParallelGCThreads 参数来设置线程数。 +默认开启的线程数量与 CPU 数量相同,可以使用 -XX:ParallelGCThreads 参数来设置线程数。 ### 3. Parallel Scavenge 收集器 @@ -365,7 +370,7 @@ Serial 翻译为串行,垃圾收集和用户程序不能同时执行,这意 CMS(Concurrent Mark Sweep),Mark Sweep 指的是标记 - 清除算法。 -特点:并发收集、低停顿。并发指的是用户线程和 GC 线程同时运行。 +特点:并发收集、低停顿。 分为以下四个流程: @@ -416,15 +421,15 @@ G1 把新生代和老年代划分成多个大小相等的独立区域(Region ### 8. 比较 -| 收集器 | 串行/并行/并发 | 新生代/老年代 | 收集算法 | 目标 | 适用场景 | +| 收集器 | 单线程/并行 | 串行/并发 | 新生代/老年代 | 收集算法 | 目标 | 适用场景 | | :---: | :---: | :---: | :---: | :---: | :---: | -| **Serial** | 串行 | 新生代 | 复制 | 响应速度优先 | 单 CPU 环境下的 Client 模式 | -| **Serial Old** | 串行 | 老年代 | 标记-整理 | 响应速度优先 | 单 CPU 环境下的 Client 模式、CMS 的后备预案 | -| **ParNew** | 串行 + 并行 | 新生代 | 复制算法 | 响应速度优先 | 多 CPU 环境时在 Server 模式下与 CMS 配合 | -| **Parallel Scavenge** | 串行 + 并行 | 新生代 | 复制算法 | 吞吐量优先 | 在后台运算而不需要太多交互的任务 | -| **Parallel Old** | 串行 + 并行 | 老年代 | 标记-整理 | 吞吐量优先 | 在后台运算而不需要太多交互的任务 | -| **CMS** | 并行 + 并发 | 老年代 | 标记-清除 | 响应速度优先 | 集中在互联网站或 B/S 系统服务端上的 Java 应用 | -| **G1** | 并行 + 并发 | 新生代 + 老年代 | 标记-整理 + 复制算法 | 响应速度优先 | 面向服务端应用,将来替换 CMS | +| **Serial** | 单线程 | 串行 | 新生代 | 复制 | 响应速度优先 | 单 CPU 环境下的 Client 模式 | +| **Serial Old** | 单线程 | 串行 | 老年代 | 标记-整理 | 响应速度优先 | 单 CPU 环境下的 Client 模式、CMS 的后备预案 | +| **ParNew** | 并行 |串行 | 新生代 | 复制算法 | 响应速度优先 | 多 CPU 环境时在 Server 模式下与 CMS 配合 | +| **Parallel Scavenge** | 并行 | 串行 | 新生代 | 复制算法 | 吞吐量优先 | 在后台运算而不需要太多交互的任务 | +| **Parallel Old** | 并行 | 串行 | 老年代 | 标记-整理 | 吞吐量优先 | 在后台运算而不需要太多交互的任务 | +| **CMS** | 并行 | 并发 | 老年代 | 标记-清除 | 响应速度优先 | 集中在互联网站或 B/S 系统服务端上的 Java 应用 | +| **G1** | 并行 | 并发 | 新生代 + 老年代 | 标记-整理 + 复制算法 | 响应速度优先 | 面向服务端应用,将来替换 CMS | ## 内存分配与回收策略