|
1 | 1 | --- |
2 | 2 | title: JVM垃圾回收详解(重点) |
3 | | -description: JVM垃圾回收详解:全面讲解GC算法(标记清除、复制、标记整理)、分代回收机制、常用垃圾回收器(Serial、Parallel、CMS、G1、ZGC)、GC调优实践。 |
| 3 | +description: JVM垃圾回收详解:全面讲解GC算法(标记清除、复制、标记整理)、分代回收机制、常用垃圾回收器(Serial、Parallel、CMS、G1、ZGC、Shenandoah)、GC调优实践。 |
4 | 4 | category: Java |
5 | 5 | tag: |
6 | 6 | - JVM |
7 | 7 | head: |
8 | 8 | - - meta |
9 | 9 | - name: keywords |
10 | | - content: JVM垃圾回收,GC算法,垃圾回收器,分代回收,标记清除,复制算法,G1 GC,ZGC,GC调优 |
| 10 | + content: JVM垃圾回收,GC算法,垃圾回收器,分代回收,标记清除,复制算法,G1 GC,ZGC,Shenandoah,GC调优 |
11 | 11 | --- |
12 | 12 |
|
13 | 13 | > 如果没有特殊说明,都是针对的是 HotSpot 虚拟机。 |
@@ -352,6 +352,8 @@ PhantomReference phantomReference2 = new PhantomReference(new String("abc"), que |
352 | 352 | - 加载该类的 `ClassLoader` 已经被回收。 |
353 | 353 | - 该类对应的 `java.lang.Class` 对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。 |
354 | 354 |
|
| 355 | +> JNI 场景下要特别小心第 3 个条件:通过 `NewGlobalRef` 创建的 `jclass` 全局引用同样会阻止类被卸载。一个常见的坑是 JNI 层缓存了反射结果:`jmethodID`/`jfieldID` 只有在类保持已加载状态时才保证有效,因此长期运行的程序通常会为 `jclass` 创建全局引用来保活。这也意味着只要这个全局引用没有释放,对应的类就永远无法卸载(参见 [issue#2908](https://github.com/Snailclimb/JavaGuide/issues/2908))。 |
| 356 | +
|
355 | 357 | 虚拟机可以对满足上述 3 个条件的无用类进行回收,这里说的仅仅是“可以”,而并不是和对象一样不使用了就会必然被回收。 |
356 | 358 |
|
357 | 359 | ## 垃圾收集算法 |
@@ -565,6 +567,22 @@ java -XX:+UseZGC className |
565 | 567 | - [新一代垃圾回收器 ZGC 的探索与实践 - 美团技术团队](https://tech.meituan.com/2020/08/06/new-zgc-practice-in-meituan.html) |
566 | 568 | - [极致八股文之 JVM 垃圾回收器 G1&ZGC 详解 - 阿里云开发者](https://mp.weixin.qq.com/s/Ywj3XMws0IIK-kiUllN87Q) |
567 | 569 |
|
| 570 | +### Shenandoah 收集器 |
| 571 | +
|
| 572 | +与 ZGC 类似,Shenandoah 也是面向低延迟的收集器,由 Red Hat 主导开发,在 Java 12 中通过 [JEP 189](https://openjdk.org/jeps/189) 以实验特性引入,Java 15 起成为正式特性([JEP 379](https://openjdk.org/jeps/379))。 |
| 573 | +
|
| 574 | +Shenandoah 的核心思路是**并发整理**:大部分堆整理工作与应用线程同时进行,暂停时间可以控制在亚毫秒级,且不受堆大小影响。它主要通过**转发指针(Brooks Pointer)**和**读屏障**实现并发整理时对象移动对应用线程的透明。 |
| 575 | +
|
| 576 | +需要注意的是,早期 Shenandoah 和早期 ZGC 一样是非分代收集器,吞吐量上有一定代价。分代 Shenandoah 仍在演进中(如 [JEP 535](https://openjdk.org/jeps/535)、[JEP 521](https://openjdk.org/jeps/521)),值得持续关注。 |
| 577 | +
|
| 578 | +你可以通过下面的参数启用 Shenandoah: |
| 579 | +
|
| 580 | +```bash |
| 581 | +java -XX:+UseShenandoahGC className |
| 582 | +``` |
| 583 | +
|
| 584 | +> 注意:Shenandoah 不在 Oracle JDK 的默认支持列表中,主要随 OpenJDK(如 Red Hat、Amazon Corretto 等发行版)提供,使用前需要确认所用 JDK 发行版是否包含并默认启用了 Shenandoah(`-XX:+PrintFlagsFinal -version | grep UseShenandoahGC`)。 |
| 585 | +
|
568 | 586 | ## 参考 |
569 | 587 |
|
570 | 588 | - 《深入理解 Java 虚拟机:JVM 高级特性与最佳实践(第二版》 |
|
0 commit comments