1
0
mirror of https://github.com/Snailclimb/JavaGuide synced 2025-06-16 18:10:13 +08:00

[docs update]jvm垃圾回收部分图片重新绘制

This commit is contained in:
guide 2022-02-10 14:58:28 +08:00
parent 4cdd53db22
commit 28eabcc895
21 changed files with 10 additions and 12 deletions

View File

@ -34,7 +34,7 @@ Java 虚拟机JVM是运行 Java 字节码的虚拟机。JVM 有针对不
除了我们平时最常用的 HotSpot VM 外,还有 J9 VM、Zing VM、JRockit VM 等 JVM 。维基百科上就有常见 JVM 的对比:[Comparison of Java virtual machines](https://en.wikipedia.org/wiki/Comparison_of_Java_virtual_machines) ,感兴趣的可以去看看。并且,你可以在 [Java SE Specifications](https://docs.oracle.com/javase/specs/index.html) 上找到各个版本的 JDK 对应的 JVM 规范。 除了我们平时最常用的 HotSpot VM 外,还有 J9 VM、Zing VM、JRockit VM 等 JVM 。维基百科上就有常见 JVM 的对比:[Comparison of Java virtual machines](https://en.wikipedia.org/wiki/Comparison_of_Java_virtual_machines) ,感兴趣的可以去看看。并且,你可以在 [Java SE Specifications](https://docs.oracle.com/javase/specs/index.html) 上找到各个版本的 JDK 对应的 JVM 规范。
![Java SE Specifications](/Users/guide/Documents/GitHub/JavaGuide/docs/java/basis/images/java-se-specifications.png) ![Java SE Specifications](./images/java-se-specifications.png)
#### JDK 和 JRE #### JDK 和 JRE

View File

@ -1,11 +1,10 @@
--- ---
title: JVM 垃圾回收详解
category: Java category: Java
tag: tag:
- JVM - JVM
--- ---
# JVM 垃圾回收详解
## 写在前面 ## 写在前面
### 本节常见面试题 ### 本节常见面试题

View File

@ -103,23 +103,21 @@ Java 虚拟机所管理的内存中最大的一块Java 堆是所有线程共
Java 世界中“几乎”所有的对象都在堆中分配,但是,随着 JIT 编译器的发展与逃逸分析技术逐渐成熟,栈上分配、标量替换优化技术将会导致一些微妙的变化,所有的对象都分配到堆上也渐渐变得不那么“绝对”了。从 JDK 1.7 开始已经默认开启逃逸分析,如果某些方法中的对象引用没有被返回或者未被外面使用(也就是未逃逸出去),那么对象可以直接在栈上分配内存。 Java 世界中“几乎”所有的对象都在堆中分配,但是,随着 JIT 编译器的发展与逃逸分析技术逐渐成熟,栈上分配、标量替换优化技术将会导致一些微妙的变化,所有的对象都分配到堆上也渐渐变得不那么“绝对”了。从 JDK 1.7 开始已经默认开启逃逸分析,如果某些方法中的对象引用没有被返回或者未被外面使用(也就是未逃逸出去),那么对象可以直接在栈上分配内存。
Java 堆是垃圾收集器管理的主要区域,因此也被称作**GC 堆Garbage Collected Heap**。从垃圾回收的角度,由于现在收集器基本都采用分代垃圾收集算法,所以 Java 堆还可以细分为新生代和老年代再细致一点有Eden 空间、From Survivor、To Survivor 空间等。**进一步划分的目的是更好地回收内存,或者更快地分配内存。** Java 堆是垃圾收集器管理的主要区域,因此也被称作**GC 堆Garbage Collected Heap**。从垃圾回收的角度,由于现在收集器基本都采用分代垃圾收集算法,所以 Java 堆还可以细分为新生代和老年代再细致一点有Eden、Survivor、Old 等空间。**进一步划分的目的是更好地回收内存,或者更快地分配内存。**
在 JDK 7 版本及 JDK 7 版本之前,堆内存被通常分为下面三部分: 在 JDK 7 版本及 JDK 7 版本之前,堆内存被通常分为下面三部分:
1. 新生代内存(Young Generation) 1. 新生代内存(Young Generation)
2. 老生代(Old Generation) 2. 老生代(Old Generation)
3. 永代(Permanent Generation) 3. 永代(Permanent Generation)
![JVM堆内存结构-JDK7](./pictures/java内存区域/JVM堆内存结构-JDK7.png) 下图所示的 Eden 区、两个 Survivor 区 S0 和 S1 都属于新生代,中间一层属于老年代,最下面一层属于永久代。
JDK 8 版本之后方法区HotSpot 的永久代被彻底移除了JDK1.7 就已经开始了),取而代之是元空间,元空间使用的是直接内存。 ![hotspot-heap-structure](./pictures/java内存区域/hotspot-heap-structure.jpg)
![JVM堆内存结构-JDK8](./pictures/java内存区域/JVM堆内存结构-jdk8.png) **JDK 8 版本之后 PermGen 已被 Metaspace(元空间) 取代,元空间使用的是直接内存。**
**上图所示的 Eden 区、两个 Survivor 区都属于新生代(为了区分,这两个 Survivor 区域按照顺序被命名为 from 和 to中间一层属于老年代。** 大部分情况,对象都会首先在 Eden 区域分配,在一次新生代垃圾回收后,如果对象还存活,则会进入 S0 或者 S1并且对象的年龄还会加 1(Eden 区->Survivor 区后对象的初始年龄变为 1),当它的年龄增加到一定程度(默认为 15 岁),就会被晋升到老年代中。对象晋升到老年代的年龄阈值,可以通过参数 `-XX:MaxTenuringThreshold` 来设置。
大部分情况,对象都会首先在 Eden 区域分配,在一次新生代垃圾回收后,如果对象还存活,则会进入 s0 或者 s1并且对象的年龄还会加 1(Eden 区->Survivor 区后对象的初始年龄变为 1),当它的年龄增加到一定程度(默认为 15 岁),就会被晋升到老年代中。对象晋升到老年代的年龄阈值,可以通过参数 `-XX:MaxTenuringThreshold` 来设置。
> **🐛 修正(参见:[issue552](https://github.com/Snailclimb/JavaGuide/issues/552)** “Hotspot 遍历所有对象时,按照年龄从小到大对其所占用的大小进行累积,当累积的某个年龄大小超过了 survivor 区的一半时,取这个年龄和 MaxTenuringThreshold 中更小的一个值,作为新的晋升年龄阈值”。 > **🐛 修正(参见:[issue552](https://github.com/Snailclimb/JavaGuide/issues/552)** “Hotspot 遍历所有对象时,按照年龄从小到大对其所占用的大小进行累积,当累积的某个年龄大小超过了 survivor 区的一半时,取这个年龄和 MaxTenuringThreshold 中更小的一个值,作为新的晋升年龄阈值”。
> >
@ -141,7 +139,7 @@ JDK 8 版本之后方法区HotSpot 的永久代被彻底移除了JDK1.7
> } > }
> ``` > ```
堆这里最容易出现的就是 OutOfMemoryError 错误,并且出现这种错误之后的表现形式还会有几种,比如: 堆这里最容易出现的就是 `OutOfMemoryError` 错误,并且出现这种错误之后的表现形式还会有几种,比如:
1. **`java.lang.OutOfMemoryError: GC Overhead Limit Exceeded`** 当 JVM 花太多时间执行垃圾回收并且只能回收很少的堆空间时,就会发生此错误。 1. **`java.lang.OutOfMemoryError: GC Overhead Limit Exceeded`** 当 JVM 花太多时间执行垃圾回收并且只能回收很少的堆空间时,就会发生此错误。
2. **`java.lang.OutOfMemoryError: Java heap space`** :假如在创建新的对象时, 堆内存中的空间不足以存放新创建的对象, 就会引发此错误。(和配置的最大堆内存有关,且受制于物理内存大小。最大堆内存可通过`-Xmx`参数配置,若没有特别配置,将会使用默认值,详见:[Default Java 8 max heap size](https://stackoverflow.com/questions/28272923/default-xmxsize-in-java-8-max-heap-size)) 2. **`java.lang.OutOfMemoryError: Java heap space`** :假如在创建新的对象时, 堆内存中的空间不足以存放新创建的对象, 就会引发此错误。(和配置的最大堆内存有关,且受制于物理内存大小。最大堆内存可通过`-Xmx`参数配置,若没有特别配置,将会使用默认值,详见:[Default Java 8 max heap size](https://stackoverflow.com/questions/28272923/default-xmxsize-in-java-8-max-heap-size))

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

@ -0,0 +1 @@
<mxfile host="Electron" modified="2022-02-10T06:48:11.793Z" agent="5.0 (Macintosh; Intel Mac OS X 10_16_0) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/13.4.5 Chrome/83.0.4103.122 Electron/9.1.0 Safari/537.36" etag="Cw0G1kXam1WciRT-fe2O" version="13.4.5" type="device"><diagram id="iqBQqmSUkrwKoGtfJ_L6" name="Page-1">3ZZdb5swFIZ/jS8nGRy+LpuMrprUalqm7HJy8AGsGhsZZ0n262eCCaFQaZWitNoV+D3HH+d5j8CIrKrDF03r8lExEMjH7IDIZ+T7nodD+2iVY6ckSdQJhebMJQ3Cmv8BJ2Kn7jiDZpRolBKG12MxU1JCZkYa1Vrtx2m5EuNda1rARFhnVEzVn5yZslNjPxr0B+BF2e/shUkXqWif7CppSsrU/kIiKSIrrZTp3qrDCkQLr+fSzbt/JXo+mAZp/mVCsYH6SW3umdjEv75W+PvTqv7kVvlNxc4VnDKQ7sDm2FPQaicZtAt5iCz3JTewrmnWRvfWd6uVphIunHMhVkoofZpLWAAxW1i9MVo9w0Uk9rckDNvIM5is7KcraVwf2IrI0p0QtIHDq6V7Z6C2E0FVYPTRphzGzeR6kPTj/eCoFzqtvHSTOJG6LirOSw+g7Ytj/Qbu/oT7Gl+XOoU4z+aoh1kM2/wW1KMPh51MsXv/G3ZCPhz2xQT7D5A7bRlfk32eQ5jNsmdRssX49h+aYAb9Ir4p+miC/hvoisq2oKvCjzOYh7+Ng0XwDvAj/O7wvWBC/0GZpra/fB9vHpEf0qrFKrdNfWKAURqgO4ziEKURWi5RQlAaoiRF8WJilyVlxp6M2Usl4YVRTqKCF9IOM0sWrL5suXN76blzgYoz1m4z2wRDm+AXRgbXMTIZG+mTqZH+nJH+2320w+EGdopd3GNJ+hc=</diagram></mxfile>

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 216 KiB

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 430 KiB

After

Width:  |  Height:  |  Size: 165 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB