cms垃圾回收机制

80 阅读2分钟

CMS(Concurrent Mark Sweep)垃圾回收器是Java虚拟机(JVM)中的一种垃圾回收算法,主要针对老年代的垃圾回收。CMS的目标是尽可能减少停顿时间,以提高应用程序的响应速度。以下是CMS垃圾回收机制的详细解释:

CMS 垃圾回收机制

1. 初始标记(Initial Mark)

  • 阶段:STW(Stop The World)
  • 操作:标记GC Roots能直接关联到的对象。
  • 特点:这个阶段非常短暂,因为只需要标记少量对象。

2. 并发标记(Concurrent Mark)

  • 阶段:并发
  • 操作:从GC Roots开始遍历整个对象图,标记所有可达对象。
  • 特点:与用户线程并发执行,不会导致STW。

3. 重新标记(Remark)

  • 阶段:STW
  • 操作:修正并发标记期间因用户程序继续运作而导致标记变化的部分对象。
  • 特点:这个阶段比初始标记稍长,但仍然相对较短。

4. 并发清除(Concurrent Sweep)

  • 阶段:并发
  • 操作:清除标记阶段发现的垃圾对象。
  • 特点:与用户线程并发执行,不会导致STW。

5. 重置(Reset)

  • 阶段:并发
  • 操作:重置CMS数据结构,为下一次垃圾回收做准备。
  • 特点:与用户线程并发执行,不会导致STW。

CMS 的优缺点

优点

  • 低停顿时间:通过并发标记和清除,减少了STW的时间,提高了应用程序的响应速度。
  • 适合交互式应用:适用于对响应时间要求较高的应用,如Web服务器、在线交易系统等。

缺点

  • 高内存消耗:需要更多的内存来保证并发回收的顺利进行,可能会导致“内存溢出”问题。
  • 浮动垃圾:在并发标记和清除阶段,可能会有新的垃圾产生,这些垃圾无法在本次GC中被回收。
  • 性能开销:并发标记和清除会占用一部分CPU资源,可能会影响应用程序的吞吐量。

配置参数

以下是一些常用的JVM参数,用于配置CMS垃圾回收器:

-XX:+UseConcMarkSweepGC          # 使用CMS垃圾回收器
-XX:ParallelCMSThreads=4         # 设置CMS线程数
-XX:CMSInitiatingOccupancyFraction=70 # 设置老年代使用率达到70%时触发CMS GC
-XX:+UseCMSCompactAtFullCollection # 在Full GC后进行压缩,减少碎片
-XX:+UseCMSInitiatingOccupancyOnly # 只有在达到指定阈值时才触发CMS GC

示例代码

以下是一个简单的示例,展示如何在Java应用程序中启用CMS垃圾回收器:

public class CMSExample {
    public static void main(String[] args) {
        // 创建大量对象,模拟内存压力
        List<byte[]> list = new ArrayList<>();
        for (int i = 0; i < 10000; i++) {
            byte[] bytes = new byte[1024 * 10]; // 10KB
            list.add(bytes);
        }

        // 模拟长时间运行
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}