垃圾收集器
什么是垃圾回收?
简单的说,JVM自动识别和释放不再被程序使用的内存。
垃圾回收的作用是清理和释放不在使用的对象,减少内存泄露和提高程序的性能和稳定性。
垃圾回收算法
垃圾回收算法见另外一篇blog:
常见的垃圾回收器
Serial 垃圾回收器
Serial垃圾回收器是单线程环境的垃圾回收器。
-
单线程执行:只能使用一个CPU核心来执行垃圾回收。
-
新生代回收:serial垃圾回收器主要用于新生代的垃圾回收,通常使用标记复制算法来清理内存。
-
效率低下:由于是单线程,所以性能相对比较差,适用于小型应用。
-
适合场景:不建议用于生产环境。可以用于测试,不太复杂的应用。
Parallel
是一种多线程的垃圾回收器,它主要针对年轻代的垃圾回收操作。有一下特点:
- 多线程:与Serial相比,是多线程回收器。它能够并行的清理内存,更快的完成垃圾回收操作。
- 新生代回收:用于新生代的垃圾回收,使用复制算法。
- 高吞吐量:以高吞吐量为目标,它通过并行执行提高吞吐量,适合多核处理器和大型应用程序。
- STW:尽管多核处理进行垃圾回收,但是仍然需要stop-the-world,需要停止应用程序所有程序来进行垃圾回收。
CMS
Concurrent Mark-Sweep,是一个基于标记-清除算法的老年代垃圾回收器。主要特点如下:
- 并发标记:CMS采用并发标记的策略,因此,垃圾回收器在应用运行期进行标记,识别哪些对象可以被清理,这阶段是并发的。
- 并发清理:标记完之后,进行清理,清理也是并发的,减少停顿时间。
- 碎片化管理:使用标记-清除算法,会导致内存碎片化。CMS还包括一些额外的步骤管理碎片化问题,如重新标记,并发清理。
- 停顿时间:依然无法消除停顿时间。
- 适合场景:CMS适用于对停顿时间要求较为严格的Java应用程序。CMS对CPU资源要求较高,可能会导致一些性能开销。
G1
Garbage-First,它采用不同于传统垃圾回收器的垃圾回收策略,主要着重于实现更可控,可预测的停顿时间,适合多核处理器和大内存的应用程序。主要特点如下:
- 分代收集:将堆内存划分为多个区域,其中包括年轻代和老年代。G1采用分代收集策略,对不同代进行不同的垃圾回收策略。
- 并发执行:G1采用并发执行的方式来进行垃圾回收,即在应用程序继续执行的情况下,同时进行垃圾回收操作。这种方式减少了应用程序暂停时间,提高了应用程序的响应能力。
- 可预测性:G1通过控制每次回收的区域数量和时间,能够在一定程度上控制垃圾回收的时间和频率,从而避免出现长时间的停顿现象。
- 空间整理:G1能够在进行垃圾回收时,同时进行空间整理操作,使得已使用的内存连续,减少了内存碎片化的问题。
- 自适应:G1能够自适应地调整垃圾回收策略,根据应用程序的垃圾产生情况和堆内存的使用情况来选择最优的垃圾回收策略。
CMS和G1区别
- 垃圾回收算法不同:CMS使用标记-清除算法,而G1使用分代复制算法。
- 内存布局不同:CMS将堆内存划分为新生代和老年代两个部分,而G1则将整个堆内存划分为多个大小相等的Region,并根据实际情况动态调整每个Region所属的内存池。
- 回收效率不同:由于采用了不同的垃圾回收算法和内存布局方式,CMS适合处理大对象、长时间运行程序;而G1则更适合处理大量短命对象、需要快速响应用户请求的程序。
- 可预测性差异:由于CMS采用并发标记清除方式进行垃圾回收,在某些情况下可能会导致停顿时间过长。而G1通过优化空间利用率以及智能地选择最有价值且最容易被释放掉的Region来避免这种问题。
- 垃圾碎片:CMS易产生垃圾碎片,G1降低内存碎片。
默认的垃圾回收器
JDK 1.8默认使用的垃圾回收器是Parallel GC(并行垃圾回收器)。它是一个基于标记-清除算法的垃圾收集器,还支持多线程以及在新生代和老年代之间进行分代收集等特性。
JDK 1.9 的默认垃圾回收器是 G1(Garbage First)回收器。G1 是一种面向服务器应用的低延迟、高吞吐量的垃圾收集器。它使用了分代垃圾收集的思想,但是不同于传统的 CMS 收集器。G1 可以同时处理不同区域的垃圾,从而达到更可控、更可预测、更可靠的垃圾回收性能。
分类
新生代:Serial,Parallel
老年代:CMS
混合:G1,ZGC
JDK1.8设置G1
查看使用的垃圾回收期
java -XX:+PrintCommandLineFlags -version
Windows环境下
set JAVA_OPTS="-XX:+UseG1GC"
Linux环境下
export JAVA_OPTS="-XX:+UseG1GC"
运行jar包
java %JAVA_OPTS% -jar your_app.jar