translated

This commit is contained in:
zzj 2022-07-24 17:56:23 +08:00
parent 00fd3028de
commit 189141fc2c
2 changed files with 121 additions and 120 deletions

View File

@ -1,120 +0,0 @@
[#]: subject: "7 kinds of garbage collection for Java"
[#]: via: "https://opensource.com/article/22/7/garbage-collection-java"
[#]: author: "Jayashree Huttanagoudar https://opensource.com/users/jayashree-huttanagoudar"
[#]: collector: "lkxed"
[#]: translator: "Veryzzj"
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
7 kinds of garbage collection for Java
======
Learn about the choices you have in Java for memory management.
An application written using programming languages like C and C++ requires you to program the destruction of objects in memory when they're no longer needed. The more your application grows, the great the probability that you'll overlook releasing unused objects. This leads to a memory leak and eventually the system memory gets used up, and at some point there's no further memory to allocate. This results in a situation where the application fails with an OutOfMemoryError. But in the case of Java, Garbage Collection (GC) happens automatically during application execution, so it alleviates the task of manual deallocation and possible memory leaks.
Garbage Collection isn't a single task. The Java Virtual Machine (JVM) has eight different kinds of Garbage Collection, and it's useful to understand each one's purpose and strength.
### 1. Serial GC
![Serial threaded garbage collection][1]
A primitive implementation of GC using just a single thread. When Garbage Collection happens, it pauses the application (commonly known as a "stop the world" event.) This is suitable for applications that can withstand small pauses. Garbage Collection has a small footprint, so this is the preferred GC type for embedded applications. This Garbage Collection style can be enabled at runtime:
```
$ java -XX:+UseSerialGC
```
### 2. Parallel GC
![Parallel garbage collection][2]
Like Serial GC, this also uses a "stop the world" method. That means that while GC is happening, application threads are paused. But in this case, there are multiple threads performing GC operation. This type of GC is suitable for applications with medium to large data sets running in a multithreaded and multiprocessor environment.
This is the default GC in JVM, and is also known as the *Throughput Collector*. Various GC parameters, like throughput, pause time, number of threads, and footprint, can be tuned with suitable JVM flags:
* Number of threads: `-XX:ParallelGCThreads=<N>`
* Pause time: `-XX:MaxGCPauseMillis=<N>`
* Throughput (time spent for GC compared to actual application execution): `-XX:GCTimeRatio=<N>`
* Maximum heap footprint: `-Xmx<N>`
* Parallel GC can be explicitly enabled: `java -XX:+UseParallelGC`. With this option, minor GC in the young generation is done with multiple threads, but GC and compaction is done with a single thread in the old generation.
There's also a version of Parallel GC called *Parallel Old GC*, which uses multiple threads for both young and old generations:
```
$ java -XX:+UseParallelOldGC
```
### 3. Concurrent Mark Sweep (CMS)
![Concurrent garbage collection][3]
Concurrent Mark Sweep (CMS) garbage collection is run alongside an application. It uses multiple threads for both minor and major GC. Compaction for live objects isn't performed in CMS GC after deleting the unused objects, so the time paused is less than in other methods. This GC runs concurrently with the application, which slows the response time of the application. This is suitable for applications with low pause time. This GC was deprecated in Java 8u, and completely removed from 14u onwards. If you're still using a Java version that has it, though, you can enable it with:
```
$ java -XX:+UseConcMarkSweepGC
```
In the case of CMS GC, the application is paused twice. It's paused first when it marks a live object that's directly reachable. This pause is known as the *initial-mark*. It's paused a second time at the end of the CMS GC phase, to account for the objects that were missed during the concurrent cycle, when application threads updated the objects after CMS GC were completed. This is known as the *remark phase*.
### 4. G1 (Garbage First) GC
![Garbage first][4]
Garbage first (G1) was meant to replace CMS. G1 GC is parallel, concurrent, and incrementally compacting, with low pause-time. G1 uses a different memory layout than CMS, dividing the heap memory into equal sized regions. G1 triggers a global mark phase with multiple threads. After the mark phase is complete, G1 knows which region might be mostly empty and chooses that region for a sweep/deletion phase first.
In the case of G1, an object that's more than half a region size is considered a "humongous object." These objects are placed in the Old generation, in a region appropriately called the *humongous region*. To enable G1:
```
$ java -XX:+UseG1GC
```
### 5. Epsilon GC
This GC was introduced in 11u and is a *no-op* (do nothing) GC. Epsilon just manages memory allocation. It doesnt do any actual memory reclamation. Epsilon is intended only when you know the exact memory footprint of your application, and knows that it is garbage collection free.
```
$ java -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC
```
### 6. Shenandoah
Shenandoah was introduced in JDK 12, and is a CPU intensive GC. It performs compaction, deletes unused objects, and release free space to the OS immediately. All of this happens in parallel with the application thread itself. To enable Shenandoah:
```
$ java -XX:+UnlockExperimentalVMOptions \
-XX:+UseShenandoahGC
```
### 7. ZGC
ZGC is designed for applications that have low latency requirements and use large heaps. ZGC allows a Java application to continue running while it performs all garbage collection operations. ZGC was introduced in JDK 11u and improved in JDK 12. Both Shenandoah and ZGC have been moved out of the experimental stage as of JDK 15. To enable ZGC:
```
$ java -XX:+UnlockExperimentalVMOptions -XX:+UseZGC
```
### Flexible garbage collection
Java provides flexibility for memory management. It's useful to get familiar with the different methods available so you can choose what's best for the application you're developing or running.
Image by: [Opensource.com][5]
--------------------------------------------------------------------------------
via: https://opensource.com/article/22/7/garbage-collection-java
作者:[Jayashree Huttanagoudar][a]
选题:[lkxed][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/jayashree-huttanagoudar
[b]: https://github.com/lkxed
[1]: https://opensource.com/sites/default/files/2022-07/jaya-java-gc-serial.webp
[2]: https://opensource.com/sites/default/files/2022-07/jaya-java-gc-parallel.webp
[3]: https://opensource.com/sites/default/files/2022-07/jaya-java-gc-concurrent.webp
[4]: https://opensource.com/sites/default/files/2022-07/g1.png
[5]: https://opensource.com/home-page-new

View File

@ -0,0 +1,121 @@
[#]: subject: "7 kinds of garbage collection for Java"
[#]: via: "https://opensource.com/article/22/7/garbage-collection-java"
[#]: author: "Jayashree Huttanagoudar https://opensource.com/users/jayashree-huttanagoudar"
[#]: collector: "lkxed"
[#]: translator: "Veryzzj"
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
七种 Java 的垃圾收集器
======
了解 Java 中的内存管理。
用 C 或 C++ 这样的编程语言写一个应用时,需要编码来销毁内存中不再需要的对象。当应用程序越进行扩展,未使用对象被忽略释放的可能性就越大。这会导致内存泄露,最终内存耗尽,在某个时刻将没有更多的内存可以分配。结果就是应用程序运行失败并出现 OutOfMemoryError。但在 Java 中垃圾收集器GC会在程序执行过程中自动运行减轻了手动分配内存和可能的内存泄漏的任务。
垃圾收集器并不只有一种Java 虚拟机( JVM有八种不同的垃圾收集器了解每种垃圾收集器的目的和优点是很有用的。
### 1. Serial 收集器
![Serial threaded garbage collection][1]
使用单线程的垃圾收集器的原始实现。当垃圾收集器运行时会停止应用程序通常称为“stop the world”事件。使用用能够承受短暂停顿的应用程序。该垃圾收集器占用内存空间比较小因此这是嵌入式应用程序的首选垃圾收集器类型。在运行时使用以下命令启用该垃圾收集器
```
$ java -XX:+UseSerialGC
```
### 2. Parallel 收集器
![Parallel garbage collection][2]
像 Serial 收集器一样Parallel 收集器也使用”stop the world”方法。这意味着当垃圾收集器运行时应用程序线程会停止。但是不同的是Parallel 收集器运行时有多个线程执行垃圾收集操作。这种类型的垃圾收集器适用于在多线程和多处理器环境中运行中到大型数据集的应用程序。
这是 JVM 中的默认垃圾收集器,也被称为*吞吐量收集器*。使用该垃圾收集器时通过使用各种合适的 JVM 参数进行调优,例如吞吐量、暂停时间、线程数和内存占用。命令如下:
* 线程数:`-XX:ParallelGCThreads=<N>`
* 暂停时间:`-XX:MaxGCPauseMillis=<N>`
* 吞吐量(垃圾收集花费的时间与实际应用程序执行的时间相比):`-XX:GCTimeRatio=<N>`
* 最大堆内存:`-Xmx<N>`
* Parallel 收集器可以使用该命令显式启用:`java -XX:+UseParallelGC` 。使用这个命令,指定在新生代中通过多个线程进行垃圾回收,而老年代中的垃圾收集和内存压缩仍使用单个线程完成的。
还有一个版本的的 Parallel 收集器叫做 *Parallel Old GC*,它对新生代和老年代都使用多线程,启用命令如下:
```
$ java -XX:+UseParallelOldGC
```
### 3. Concurrent Mark SweepCMS收集器
![Concurrent garbage collection][3]
Concurrent Mark SweepCMS 垃圾收集器与应用程序并行运行。对于新生代和老年代都使用了多线程。在CMS垃圾收集器删除无用对象后不会对存活对象进行内存压缩。该垃圾收集器和应用程序并行运行会降低应用程序的响应时间适用于停顿时间较短的应用程序。这个收集器在 Java8 已过时,并在 Java14 中被移除。如果你仍在使用有这个垃圾收集器的 Java 版本,可以使用如下命令启用:
```
$ java -XX:+UseConcMarkSweepGC
```
在 CMS 垃圾收集器使用过程中,应用程序将暂停两次。首次暂停发生在标记可直接访问的存活对象时,这个暂停被称为*初始标记*。第二次暂停发生在 CMS 收集器结束时期,来修正在并发标记过程中,应用程序线程在 CMS 垃圾回收完成后更新对象时被遗漏的对象。这就是所谓的*重新标记*。
### 4. G1 收集器
![Garbage first][4]
G1垃圾收集器旨在替代 GMS。G1 垃圾收集器具备并行、并发以及增量压缩,且暂停时间较短。与 CMS 收集器使用的内存布局不同G1 收集器将堆内存划分为大小相同的区域通过多个线程触发全局标记阶段。标记阶段完成后G1 知道哪个区域可能大部分是空的,并首选该区域作为清除/删除阶段。
在 G1 收集器中,一个对象如果大小超过半个区域容量会被认为是一个“大对象” 。这些对象被放置在老年代中,在一个被称为*humongous region*的区域中。 启用 G1 收集器的命令如下:
```
$ java -XX:+UseG1GC
```
### 5. Epsilon 收集器
该垃圾收集器是在 Java11 中引入的,是一个 *no-op*无操作收集器。它不做任何实际的内存回收只负责管理内存分配。Epsilon 只在当你知道应用程序的确切内存占用情况并且不需要垃圾回收时使用。启用命令如下:
```
$ java -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC
```
### 6. Shenandoah 收集器
Shenandoah 是在 JDK12 中引入的是一种CPU密集型垃圾收集器。它会进行内存压缩立即删除无用对象并释放操作系统的空间。所有的这一切与应用程序线程并行发生。启用命令如下
```
$ java -XX:+UnlockExperimentalVMOptions \
-XX:+UseShenandoahGC
```
### 7. ZGC收集器
ZGC 为低延迟需要和大量堆空间使用而设计,允许当垃圾回收器运行时 Java 应用程序继续运行。 ZGC 收集器在 JDK11 引入,在 JDK12 改进。在 JDK15ZGC 和 Shenandoah 都被移出了实验阶段。启用 ZGC 收集器使用如下命令:
```
$ java -XX:+UnlockExperimentalVMOptions -XX:+UseZGC
```
### 灵活的垃圾收集器
Java 为我们提供了灵活的内存管理方式,熟悉不同的可用方法有助于为正在开发或运行的应用程序选择最合适的内存管理方式。
Image by: [Opensource.com][5]
--------------------------------------------------------------------------------
via: https://opensource.com/article/22/7/garbage-collection-java
作者:[Jayashree Huttanagoudar][a]
选题:[lkxed][b]
译者:[Veryzzj](https://github.com/Veryzzj)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/jayashree-huttanagoudar
[b]: https://github.com/lkxed
[1]: https://opensource.com/sites/default/files/2022-07/jaya-java-gc-serial.webp
[2]: https://opensource.com/sites/default/files/2022-07/jaya-java-gc-parallel.webp
[3]: https://opensource.com/sites/default/files/2022-07/jaya-java-gc-concurrent.webp
[4]: https://opensource.com/sites/default/files/2022-07/g1.png
[5]: https://opensource.com/home-page-new