auto commit

This commit is contained in:
CyC2018 2018-06-19 14:29:02 +08:00
parent ce16713e80
commit b142426c33

View File

@ -8,7 +8,7 @@
* [运行时常量池](#运行时常量池) * [运行时常量池](#运行时常量池)
* [直接内存](#直接内存) * [直接内存](#直接内存)
* [二、垃圾收集](#二垃圾收集) * [二、垃圾收集](#二垃圾收集)
* [判断一个对象是否可回收](#判断一个对象是否可回收) * [判断一个对象是否存活](#判断一个对象是否存活)
* [垃圾收集算法](#垃圾收集算法) * [垃圾收集算法](#垃圾收集算法)
* [垃圾收集器](#垃圾收集器) * [垃圾收集器](#垃圾收集器)
* [内存分配与回收策略](#内存分配与回收策略) * [内存分配与回收策略](#内存分配与回收策略)
@ -61,16 +61,18 @@ java -Xss=512M HackTheJava
所有对象实例都在这里分配内存。 所有对象实例都在这里分配内存。
是垃圾收集的主要区域("GC 堆",现代的垃圾收集器基本都是采用分代收集算法,该算法的思想是针对不同的对象采取不同的垃圾回收算法,因此虚拟机把 Java 堆分成以下三块: 是垃圾收集的主要区域("GC 堆"。现代的垃圾收集器基本都是采用分代收集算法,主要思想是针对不同的对象采取不同的垃圾回收算法。虚拟机把 Java 堆分成以下三块:
- 新生代Young Generation - 新生代Young Generation
- 老年代Old Generation - 老年代Old Generation
- 永久代Permanent Generation - 永久代Permanent Generation
当一个对象被创建时,它首先进入新生代,之后有可能被转移到老年代中。新生代存放着大量的生命很短的对象,因此新生代在三个区域中垃圾回收的频率最高。为了更高效地进行垃圾回收,把新生代继续划分成以下三个空间: 当一个对象被创建时,它首先进入新生代,之后有可能被转移到老年代中。
- Eden 新生代存放着大量的生命很短的对象,因此新生代在三个区域中垃圾回收的频率最高。为了更高效地进行垃圾回收,把新生代继续划分成以下三个空间:
- From Survivor
- Eden伊甸园
- From Survivor幸存者
- To Survivor - To Survivor
<div align="center"> <img src="../pics//ppt_img.gif" width=""/> </div><br> <div align="center"> <img src="../pics//ppt_img.gif" width=""/> </div><br>
@ -99,7 +101,7 @@ JDK 1.7 之前HotSpot 虚拟机把它当成永久代来进行垃圾回收J
Class 文件中的常量池(编译器生成的各种字面量和符号引用)会在类加载后被放入这个区域。 Class 文件中的常量池(编译器生成的各种字面量和符号引用)会在类加载后被放入这个区域。
除了在编译期生成的常量,还允许动态生成,例如 String 类的 intern()。这部分常量也会被放入运行时常量池。 除了在编译期生成的常量,还允许动态生成,例如 String 类的 intern()。
## 直接内存 ## 直接内存
@ -109,11 +111,11 @@ Class 文件中的常量池(编译器生成的各种字面量和符号引用
程序计数器、虚拟机栈和本地方法栈这三个区域属于线程私有的,只存在于线程的生命周期内,线程结束之后也会消失,因此不需要对这三个区域进行垃圾回收。垃圾回收主要是针对 Java 堆和方法区进行。 程序计数器、虚拟机栈和本地方法栈这三个区域属于线程私有的,只存在于线程的生命周期内,线程结束之后也会消失,因此不需要对这三个区域进行垃圾回收。垃圾回收主要是针对 Java 堆和方法区进行。
## 判断一个对象是否可回收 ## 判断一个对象是否存活
### 1. 引用计数算法 ### 1. 引用计数算法
给对象添加一个引用计数器,当对象增加一个引用时计数器加 1引用失效时计数器减 1。引用计数为 0 的对象可被回收 给对象添加一个引用计数器,当对象增加一个引用时计数器加 1引用失效时计数器减 1。引用计数不为 0 的对象仍然存活
两个对象出现循环引用的情况下,此时引用计数器永远不为 0导致无法对它们进行回收。 两个对象出现循环引用的情况下,此时引用计数器永远不为 0导致无法对它们进行回收。
@ -147,7 +149,7 @@ Java 虚拟机使用该算法来判断对象是否可被回收,在 Java 中 GC
### 3. 引用类型 ### 3. 引用类型
无论是通过引用计算算法判断对象的引用数量,还是通过可达性分析算法判断对象的引用链是否可达,判定对象是否可被回收都与引用有关。 无论是通过引用计算算法判断对象的引用数量,还是通过可达性分析算法判断对象是否可达,判定对象是否可被回收都与引用有关。
Java 具有四种强度不同的引用类型。 Java 具有四种强度不同的引用类型。
@ -170,7 +172,7 @@ Object obj = new Object();
```java ```java
Object obj = new Object(); Object obj = new Object();
SoftReference<Object> sf = new SoftReference<Object>(obj); SoftReference<Object> sf = new SoftReference<Object>(obj);
obj = null; // 使对象只被软引用关联 obj = null; // 使对象只被软引用关联
``` ```
**(三)弱引用** **(三)弱引用**
@ -270,7 +272,7 @@ finalize() 类似 C++ 的析构函数,用来做关闭外部资源等工作。
<div align="center"> <img src="../pics//a4248c4b-6c1d-4fb8-a557-86da92d3a294.jpg" width=""/> </div><br> <div align="center"> <img src="../pics//a4248c4b-6c1d-4fb8-a557-86da92d3a294.jpg" width=""/> </div><br>
需要存活的对象进行标记,然后清理掉未被标记的对象。 将存活的对象进行标记,然后清理掉未被标记的对象。
不足: 不足:
@ -308,11 +310,14 @@ finalize() 类似 C++ 的析构函数,用来做关闭外部资源等工作。
以上是 HotSpot 虚拟机中的 7 个垃圾收集器,连线表示垃圾收集器可以配合使用。 以上是 HotSpot 虚拟机中的 7 个垃圾收集器,连线表示垃圾收集器可以配合使用。
- 单线程与并行(多线程):单线程指的是垃圾收集器只使用一个线程进行收集,而并行使用多个线程。
- 串行与并发:串行指的是垃圾收集器与用户程序交替执行,这意味着在执行垃圾收集的时候需要停顿用户程序;并发指的是垃圾收集器和用户程序同时执行。除了 CMS 和 G1 之外,其它垃圾收集器都是以串行的方式执行。
### 1. Serial 收集器 ### 1. Serial 收集器
<div align="center"> <img src="../pics//22fda4ae-4dd5-489d-ab10-9ebfdad22ae0.jpg" width=""/> </div><br> <div align="center"> <img src="../pics//22fda4ae-4dd5-489d-ab10-9ebfdad22ae0.jpg" width=""/> </div><br>
Serial 翻译为串行,垃圾收集和用户程序不能同时执行,这意味着在执行垃圾收集的时候需要停顿用户程序。除了 CMS 和 G1 之外其它收集器都是以串行的方式执行。CMS 和 G1 可以使得垃圾收集和用户程序同时执行,被称为并发执行。 Serial 翻译为串行,也就是说它以串行的方式执行。
它是单线程的收集器,只会使用一个线程进行垃圾收集工作。 它是单线程的收集器,只会使用一个线程进行垃圾收集工作。
@ -328,7 +333,7 @@ Serial 翻译为串行,垃圾收集和用户程序不能同时执行,这意
是 Server 模式下的虚拟机首选新生代收集器,除了性能原因外,主要是因为除了 Serial 收集器,只有它能与 CMS 收集器配合工作。 是 Server 模式下的虚拟机首选新生代收集器,除了性能原因外,主要是因为除了 Serial 收集器,只有它能与 CMS 收集器配合工作。
默认开的线程数量与 CPU 数量相同,可以使用 -XX:ParallelGCThreads 参数来设置线程数。 默认开的线程数量与 CPU 数量相同,可以使用 -XX:ParallelGCThreads 参数来设置线程数。
### 3. Parallel Scavenge 收集器 ### 3. Parallel Scavenge 收集器
@ -365,7 +370,7 @@ Serial 翻译为串行,垃圾收集和用户程序不能同时执行,这意
CMSConcurrent Mark SweepMark Sweep 指的是标记 - 清除算法。 CMSConcurrent Mark SweepMark Sweep 指的是标记 - 清除算法。
特点:并发收集、低停顿。并发指的是用户线程和 GC 线程同时运行。 特点:并发收集、低停顿。
分为以下四个流程: 分为以下四个流程:
@ -416,15 +421,15 @@ G1 把新生代和老年代划分成多个大小相等的独立区域Region
### 8. 比较 ### 8. 比较
| 收集器 | 串行/并行/并发 | 新生代/老年代 | 收集算法 | 目标 | 适用场景 | | 收集器 | 单线程/并行 | 串行/并发 | 新生代/老年代 | 收集算法 | 目标 | 适用场景 |
| :---: | :---: | :---: | :---: | :---: | :---: | | :---: | :---: | :---: | :---: | :---: | :---: |
| **Serial** | 串行 | 新生代 | 复制 | 响应速度优先 | 单 CPU 环境下的 Client 模式 | | **Serial** | 单线程 | 串行 | 新生代 | 复制 | 响应速度优先 | 单 CPU 环境下的 Client 模式 |
| **Serial Old** | 串行 | 老年代 | 标记-整理 | 响应速度优先 | 单 CPU 环境下的 Client 模式、CMS 的后备预案 | | **Serial Old** | 单线程 | 串行 | 老年代 | 标记-整理 | 响应速度优先 | 单 CPU 环境下的 Client 模式、CMS 的后备预案 |
| **ParNew** | 串行 + 并行 | 新生代 | 复制算法 | 响应速度优先 | 多 CPU 环境时在 Server 模式下与 CMS 配合 | | **ParNew** | 并行 |串行 | 新生代 | 复制算法 | 响应速度优先 | 多 CPU 环境时在 Server 模式下与 CMS 配合 |
| **Parallel Scavenge** | 串行 + 并行 | 新生代 | 复制算法 | 吞吐量优先 | 在后台运算而不需要太多交互的任务 | | **Parallel Scavenge** | 并行 | 串行 | 新生代 | 复制算法 | 吞吐量优先 | 在后台运算而不需要太多交互的任务 |
| **Parallel Old** | 串行 + 并行 | 老年代 | 标记-整理 | 吞吐量优先 | 在后台运算而不需要太多交互的任务 | | **Parallel Old** | 并行 | 串行 | 老年代 | 标记-整理 | 吞吐量优先 | 在后台运算而不需要太多交互的任务 |
| **CMS** | 并行 + 并发 | 老年代 | 标记-清除 | 响应速度优先 | 集中在互联网站或 B/S 系统服务端上的 Java 应用 | | **CMS** | 并行 | 并发 | 老年代 | 标记-清除 | 响应速度优先 | 集中在互联网站或 B/S 系统服务端上的 Java 应用 |
| **G1** | 并行 + 并发 | 新生代 + 老年代 | 标记-整理 + 复制算法 | 响应速度优先 | 面向服务端应用,将来替换 CMS | | **G1** | 并行 | 并发 | 新生代 + 老年代 | 标记-整理 + 复制算法 | 响应速度优先 | 面向服务端应用,将来替换 CMS |
## 内存分配与回收策略 ## 内存分配与回收策略