一、GC
1.1、目标
GC的主要作用是自动识别和释放不再使用的对象,回收其所占用的内存,以防止内存泄漏和内存溢出的问题。
1.2、如何实现
1.2.1、标记阶段
GC从根对象(如线程栈中的引用、静态变量等)开始,通过可达性分析算法标记所有与根对象直接或间接关联的对象。
标记技术法
可达性分析法
1.2.2、清除阶段:
GC遍历堆中的所有对象,清除未被标记的对象,以释放其占用的内存。
1.2.3、压缩阶段(可选):
GC可以选择对堆进行压缩操作,将存活对象紧凑排列,以减少内存碎片和提高内存利用率。
1.3、GC的优点包括:
1.3.1、自动内存管理:
GC可以自动识别和回收不再使用的对象,减轻了程序员手动释放内存的负担。
1.3.2、避免内存泄漏:
GC可以自动回收无法通过程序访问到的对象,避免了因为忘记释放内存而导致的内存泄漏问题。
1.3.3、避免内存溢出:
GC可以动态地管理内存,及时回收不再使用的对象,避免了因为内存不足而导致的内存溢出问题。
1.4、GC的缺点包括:
1.4.1、垃圾回收的开销
GC需要消耗一定的CPU和内存资源来执行垃圾回收操作,可能会对程序的性能造成一定的影响。
1.4.2、程序暂停时间
在执行GC时,所有的线程都会被暂停,直到GC完成。这会导致程序在执行GC时出现明显的停顿,对于实时性要求较高的应用可能会有影响。
为了更好地利用GC,可以采取以下措施:
1、优化对象的生命周期,尽量减少对象的创建和销毁,避免频繁的GC操作。
2、合理设置堆大小和GC参数,根据应用的实际情况进行调优。
3、避免创建过多的临时对象,可以使用对象池或复用对象的方式来减少GC的开销。
总之,GC是Java的一项重要特性,有效的GC策略可以提高程序的性能和稳定性,但需要根据具体应用的需求和场景来进行调整和优化。
二、CMS
是一种用于Java的垃圾回收器,它被设计用来减少垃圾回收的停顿时间,尤其适用于对响应时间要求较高的应用。
2.1、工作原理
1、初始标记阶段(Initial Mark):暂停所有应用线程,标记所有与根对象直接关联的对象。
2、并发标记阶段(Concurrent Mark):与应用线程并发执行,标记所有与根对象间接关联的对象。
3、并发预清理阶段(Concurrent Pre-clean):与应用线程并发执行,处理一些在并发标记期间发生变动的对象。
4、最终标记阶段(Final Remark):暂停所有应用线程,完成标记过程,确保标记的准确性。
5、并发清除阶段(Concurrent Sweep):与应用线程并发执行,对未被标记的对象进行清除回收。
2.2、优点
1、低暂停时间:CMS通过将垃圾回收的过程与应用线程并发执行,减少了垃圾回收的暂停时间,从而降低了对应用响应时间的影响。
2、分阶段执行:CMS将垃圾回收分为多个阶段,并与应用线程并发执行,减少了对应用的影响。
2.3、缺点
1、不压缩内存:CMS不会对堆进行整理压缩操作,从而避免了长时间的停顿,但可能导致堆内存碎片增多。
2、需要更多的CPU资源:由于并发执行的关系,CMS需要更多的CPU资源来执行垃圾回收操作。
需要注意的是,CMS并不是适用于所有场景的垃圾回收器。由于并发执行的特性,CMS可能导致堆内存的碎片化增多,并且因为并发执行的开销,可能会对应用的吞吐量产生一定的影响。因此,在选择GC策略时,需要根据应用的实际情况进行评估和选择。
三、G1
G1(Garbage-First)是一种新的垃圾回收器,引入了全新的垃圾回收算法和内存布局方式。相比于CMS和其他传统的垃圾回收器,G1在处理大堆、低延迟和高吞吐量场景下具有更好的性能表现
3.1、工作原理
1、分区布局:G1将堆划分为多个大小相等的分区(Region),每个分区可以是Eden区、Survivor区或者Old区。这种分区布局可以提供更细粒度的内存管理。
2、并发标记:G1使用并发标记算法来进行标记阶段,与应用线程并发执行,以减少垃圾回收的停顿时间。
3、并发清理:G1使用并发清理算法来进行分区的清理,与应用线程并发执行,以减少垃圾回收的停顿时间。
4、混合回收:G1采用了混合回收的方式,在标记和清理阶段之间可以执行一部分回收操作,以进一步减少垃圾回收的停顿时间。
5、优先处理垃圾多的分区:G1的名字"Garbage-First"就是因为其优先处理垃圾多的分区。G1会根据分区内垃圾的多少来优先选择最需要回收的分区,以达到更高的吞吐量。
3.2、优点
1、可预测的停顿时间:G1通过控制每次垃圾回收的停顿时间,可以提供可预测的垃圾回收性能,尤其适用于对低延迟有要求的应用。
2、高吞吐量:G1采用并行和并发的方式执行垃圾回收,可以在保证低延迟的同时,提供较高的吞吐量,适合处理大堆的应用场景。
3、内存整理:G1在回收过程中可以进行部分的内存整理,减少内存碎片,提高内存利用率。
4、可预测的逐步增量:G1通过划分多个分区,并以逐步增量的方式执行垃圾回收,可以更好地控制回收的进度。
需要注意的是,G1并不是适用于所有场景的垃圾回收器。在一些极端情况下,如大量短期存活的对象或大量大对象的情况下,G1的性能可能不如其他垃圾回收器。因此,在选择GC策略时,需要根据应用的实际情况进行评估和选择。
四、CMS和G1的对比
1、垃圾回收方式:CMS采用并发标记和并发清除的方式来进行垃圾回收,即在应用线程并发执行的同时,进行标记和清除操作。而G1采用分代混合收集的方式,将堆划分为多个分区,并在标记和清理之间执行一部分回收操作。
2、堆布局:CMS并不对堆进行特殊的布局,而G1采用了分区布局,将堆划分为多个大小相等的分区。
3、停顿时间:CMS的目标是减少垃圾回收的停顿时间,特别适用于低延迟要求较高的应用。它通过并发执行的方式尽量减少对应用线程的影响。而G1也注重减少垃圾回收的停顿时间,但它通过可预测的停顿时间来提供更好的性能,尤其适用于对停顿时间有严格要求的应用。
4、内存整理:CMS在回收过程中不会对内存进行压缩整理,可能会导致堆内存碎片增多。而G1可以在回收过程中进行部分的内存整理,减少内存碎片,提高内存利用率。
5、吞吐量:CMS主要关注降低停顿时间,但可能会对应用的吞吐量产生一定的影响。而G1在保证低延迟的同时,也提供了较高的吞吐量,适用于需要处理大堆的应用场景。
综上所述,CMS适用于对低延迟有要求的场景,重点在于减少停顿时间。而G1适用于对停顿时间和吞吐量都有较高要求的场景,通过分区布局和可预测的停顿时间提供更好的性能。在实际选择时,需要根据应用的实际情况和具体需求来进行评估和选择。