1.JVM GC算法
1.1 标记-清除算法
标记-清除算法是最基本的垃圾回收算法之一。它分为两个阶段:标记和清除。
首先,从根对象开始,标记所有可以被访问到的对象。标记完成后,遍历堆内存,将未被标记的对象回收。
该算法的优点是简单易懂,缺点是容易产生内存碎片。
1.2 复制算法
复制算法将堆内存划分为两个区域:From区和To区。在进行垃圾回收时,首先将存活对象从From区复制到To区,然后清空From区,并交换From区和To区的角色。
该算法的优点是回收效率高,缺点是只能使用堆内存的一半。
1.3 标记-整理算法
标记-整理算法是在标记-清除算法的基础上进行优化的算法。它将存活对象向一端移动,然后清理边界以外的内存。
该算法的优点是解决了标记-清除算法的内存碎片问题,缺点是效率相对较低。
1.4 分代算法
分代算法是根据对象的存活周期将堆内存划分为不同的区域,然后根据不同区域的特点使用不同的垃圾回收算法。
一般来说,将堆内存划分为新生代和老年代。新生代使用复制算法,老年代使用标记-清除或标记-整理算法。
该算法的优点是充分利用了对象的存活周期特点,提高了垃圾回收效率。
2.GC种类
2.1 Serial GC
Serial GC是一种单线程的垃圾回收器,它使用复制算法来回收新生代,使用标记-整理算法来回收老年代。
Serial GC适用于单核CPU和小内存的环境,它的优点是简单高效,缺点是无法充分利用多核CPU的优势。
2.2 Parallel GC
Parallel GC是一种多线程的垃圾回收器,它使用复制算法来回收新生代,使用标记-整理算法来回收老年代。
Parallel GC适用于多核CPU和大内存的环境,它的优点是回收效率高,缺点是会占用较多的CPU资源。
2.3 CMS GC
CMS(Concurrent Mark Sweep)GC是一种并发的垃圾回收器,它使用标记-清除算法来回收老年代。
CMS GC的特点是在回收老年代时,尽量减少应用程序的停顿时间。它会在应用程序运行的同时进行垃圾回收,但会占用一定的CPU资源。
2.4 G1 GC
G1(Garbage First)GC是一种面向服务端应用的垃圾回收器,它使用标记-整理算法来回收堆内存。
G1 GC的特点是将堆内存划分为多个region,每个region可以是新生代或老年代。它可以根据应用程序的需求动态调整回收区域的大小,以达到更好的回收效果。
2.5 ZGC
ZGC是一种低停顿时间的垃圾回收器,它使用标记-整理算法来回收堆内存。
ZGC的特点是将堆内存划分为多个region,每个region可以是新生代或老年代。它通过并发的方式来进行垃圾回收,以减少应用程序的停顿时间。
2.6 Shenandoah GC
Shenandoah GC是一种低停顿时间的垃圾回收器,它使用标记-清除算法来回收堆内存。
Shenandoah GC的特点是通过并发的方式来进行垃圾回收,并在回收过程中允许应用程序继续运行,以减少停顿时间。
2.7 Epsilon GC
Epsilon GC是一种不进行垃圾回收的垃圾回收器,它什么都不做,只是简单地分配内存。
Epsilon GC适用于一些特殊场景,例如性能测试和内存分析等,它的特点是没有任何停顿时间,但会导致内存溢出。
3.示例代码
下面是一个简单的Java代码示例,演示了如何使用Serial GC来进行垃圾回收。
public class SerialGCDemo { public static void main(String[] args) { // 设置使用Serial GC System.setProperty("java.vm.useSerialGC", "true"); // 创建大对象,触发垃圾回收 byte[] array = new byte[1024 * 1024 * 10]; // 查看垃圾回收信息 long startTime = System.currentTimeMillis(); System.gc(); long endTime = System.currentTimeMillis(); System.out.println("垃圾回收耗时:" + (endTime - startTime) + "ms"); } } |
以上代码中,通过设置java.vm.useSerialGC
系统属性为true
来使用Serial GC。然后创建了一个大小为10MB的字节数组,触发了垃圾回收。最后打印出垃圾回收的耗时。
在实际应用中,可以根据具体需求选择合适的垃圾回收器,并根据应用程序的特点进行调优,以提高性能和减少停顿时间。