mirror of
https://github.com/Snailclimb/JavaGuide
synced 2025-06-16 18:10:13 +08:00
Update 搞定JVM垃圾回收就是这么简单.md
This commit is contained in:
parent
15fc507aff
commit
c8bb5cb0f7
@ -1,8 +1,43 @@
|
||||
|
||||
上文回顾:[《可能是把Java内存区域讲的最清楚的一篇文章》](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484303&idx=1&sn=af0fd436cef755463f59ee4dd0720cbd&chksm=fd9855eecaefdcf8d94ac581cfda4e16c8a730bda60c3b50bc55c124b92f23b6217f7f8e58d5&token=506869459&lang=zh_CN#rd)
|
||||
<!-- TOC -->
|
||||
|
||||
- [JVM 垃圾回收](#jvm-垃圾回收)
|
||||
- [写在前面](#写在前面)
|
||||
- [本节常见面试题](#本节常见面试题)
|
||||
- [本文导火索](#本文导火索)
|
||||
- [1 揭开 JVM 内存分配与回收的神秘面纱](#1--揭开-jvm-内存分配与回收的神秘面纱)
|
||||
- [1.1 对象优先在 eden 区分配](#11-对象优先在-eden-区分配)
|
||||
- [1.2 大对象直接进入老年代](#12-大对象直接进入老年代)
|
||||
- [1.3 长期存活的对象将进入老年代](#13-长期存活的对象将进入老年代)
|
||||
- [1.4 动态对象年龄判定](#14-动态对象年龄判定)
|
||||
- [2 对象已经死亡?](#2-对象已经死亡)
|
||||
- [2.1 引用计数法](#21-引用计数法)
|
||||
- [2.2 可达性分析算法](#22-可达性分析算法)
|
||||
- [2.3 再谈引用](#23-再谈引用)
|
||||
- [2.4 不可达的对象并非“非死不可”](#24-不可达的对象并非非死不可)
|
||||
- [2.5 如何判断一个常量是废弃常量](#25-如何判断一个常量是废弃常量)
|
||||
- [2.6 如何判断一个类是无用的类](#26-如何判断一个类是无用的类)
|
||||
- [3 垃圾收集算法](#3-垃圾收集算法)
|
||||
- [3.1 标记-清除算法](#31-标记-清除算法)
|
||||
- [3.2 复制算法](#32-复制算法)
|
||||
- [3.3 标记-整理算法](#33-标记-整理算法)
|
||||
- [3.4 分代收集算法](#34-分代收集算法)
|
||||
- [4 垃圾收集器](#4-垃圾收集器)
|
||||
- [4.1 Serial 收集器](#41-serial-收集器)
|
||||
- [4.2 ParNew 收集器](#42-parnew-收集器)
|
||||
- [4.3 Parallel Scavenge 收集器](#43-parallel-scavenge-收集器)
|
||||
- [4.4.Serial Old 收集器](#44serial-old-收集器)
|
||||
- [4.5 Parallel Old 收集器](#45-parallel-old-收集器)
|
||||
- [4.6 CMS 收集器](#46-cms-收集器)
|
||||
- [4.7 G1 收集器](#47-g1-收集器)
|
||||
- [参考](#参考)
|
||||
|
||||
<!-- /TOC -->
|
||||
# JVM 垃圾回收
|
||||
|
||||
## 写在前面
|
||||
|
||||
### 本节常见面试题:
|
||||
### 本节常见面试题
|
||||
|
||||
问题答案在文中都有提到
|
||||
|
||||
@ -22,8 +57,6 @@
|
||||
|
||||
当需要排查各种 内存溢出问题、当垃圾收集成为系统达到更高并发的瓶颈时,我们就需要对这些“自动化”的技术实施必要的监控和调节。
|
||||
|
||||
|
||||
|
||||
## 1 揭开 JVM 内存分配与回收的神秘面纱
|
||||
|
||||
Java 的自动内存管理主要是针对对象内存的回收和对象内存的分配。同时,Java 自动内存管理最核心的功能是 **堆** 内存中对象的分配与回收。
|
||||
@ -38,9 +71,7 @@ Java 堆是垃圾收集器管理的主要区域,因此也被称作**GC堆(Ga
|
||||
|
||||
上图所示的 eden 区、s0 区、s1 区都属于新生代,tentired 区属于老年代。大部分情况,对象都会首先在 Eden 区域分配,在一次新生代垃圾回收后,如果对象还存活,则会进入 s0 或者 s1,并且对象的年龄还会加 1(Eden 区->Survivor 区后对象的初始年龄变为 1),当它的年龄增加到一定程度(默认为 15 岁),就会被晋升到老年代中。对象晋升到老年代的年龄阈值,可以通过参数 `-XX:MaxTenuringThreshold` 来设置。
|
||||
|
||||
|
||||
|
||||

|
||||

|
||||
|
||||
### 1.1 对象优先在 eden 区分配
|
||||
|
||||
@ -218,7 +249,7 @@ JDK1.2以后,Java对引用的概念进行了扩充,将引用分为强引用
|
||||
|
||||
## 3 垃圾收集算法
|
||||
|
||||

|
||||

|
||||
|
||||
### 3.1 标记-清除算法
|
||||
|
||||
@ -227,13 +258,13 @@ JDK1.2以后,Java对引用的概念进行了扩充,将引用分为强引用
|
||||
1. **效率问题**
|
||||
2. **空间问题(标记清除后会产生大量不连续的碎片)**
|
||||
|
||||

|
||||
<img src="http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-8-27/63707281.jpg" alt="公众号" width="500px">
|
||||
|
||||
### 3.2 复制算法
|
||||
|
||||
为了解决效率问题,“复制”收集算法出现了。它可以将内存分为大小相同的两块,每次使用其中的一块。当这一块的内存使用完后,就将还存活的对象复制到另一块去,然后再把使用的空间一次清理掉。这样就使每次的内存回收都是对内存区间的一半进行回收。
|
||||
|
||||

|
||||
<img src="http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-8-27/90984624.jpg" alt="公众号" width="500px">
|
||||
|
||||
### 3.3 标记-整理算法
|
||||
根据老年代的特点特出的一种标记算法,标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象回收,而是让所有存活的对象向一端移动,然后直接清理掉端边界以外的内存。
|
||||
@ -252,7 +283,7 @@ JDK1.2以后,Java对引用的概念进行了扩充,将引用分为强引用
|
||||
|
||||
## 4 垃圾收集器
|
||||
|
||||

|
||||

|
||||
|
||||
**如果说收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的具体实现。**
|
||||
|
||||
@ -357,12 +388,11 @@ G1收集器的运作大致分为以下几个步骤:
|
||||
|
||||
**G1 收集器在后台维护了一个优先列表,每次根据允许的收集时间,优先选择回收价值最大的 Region(这也就是它的名字 Garbage-First 的由来)**。这种使用 Region 划分内存空间以及有优先级的区域回收方式,保证了 GF 收集器在有限时间内可以尽可能高的收集效率(把内存化整为零)。
|
||||
|
||||
|
||||
|
||||
## 参考
|
||||
|
||||
- 《深入理解 Java 虚拟机:JVM 高级特性与最佳实践(第二版》
|
||||
- https://my.oschina.net/hosee/blog/644618
|
||||
- <https://docs.oracle.com/javase/specs/jvms/se8/html/index.html>
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user