JVM 垃圾回收

1.基本概念:      

        垃圾回收(Garbage Collection, GC)是自动内存管理的一种机制,用于回收程序运行过程中不再使用的对象所占用的内存空间。在编程语言(如Java、Python等)中,垃圾回收机制有助于减少内存泄漏和内存管理的复杂性。垃圾回收算法和回收器是实现这一机制的核心部分。

2.垃圾回收算法:

        (1).引用计数算法:

  • 基本思想:每个对象都有一个引用计数器,记录有多少个引用指向该对象。当一个对象的引用计数为0时,该对象会被立即回收。
  • 优点:实现简单,对象的回收是及时的。
  • 缺点:无法处理循环引用(即两个对象互相引用)。

        (2).标记-清除算法:

  • 基本思想:GC暂停程序的执行,遍历所有的对象,将所有可达的对象进行标记,然后清除未被标记的对象。
  • 优点:能够处理循环引用,回收所有不再使用的对象。
  • 缺点:需要暂停程序执行("Stop-The-World"),导致停顿时间较长,且清理后可能会产生内存碎片,分配速度慢。

        (3).复制算法:   

  • 基本思想:将内存分为两个区域(如"From"和"To"),每次GC时将存活的对象从一个区域复制到另一个区域,然后清空原来的区域。
  • 优点:高效地分配和回收内存(分配速度快),不会产生碎片。
  • 缺点:需要双倍的内存空间(只能使用一半的内存空间),内存利用率较低。

       

        (4).标记-整理算法:

  • 基本思想:与标记-清除类似,通过可达性分析标记所有被引用的对象。然后,在整理阶段,将所有存活的对象向一端移动,并且清理掉末尾的垃圾对象
  • 优点:没有内存碎片,提高内存利用率。
  • 缺点:整理阶段需要良好的算法,否则效率不高。

        (5).分代GC:

  • 基本思想:将堆内存分为多个代(一般为年轻代和老年代),不同代使用不同的GC策略。年轻代频繁回收,老年代回收频率较低。
  • 优点:提高了GC的效率,减少了GC停顿时间。
  • 缺点:实现复杂,需要适应不同对象的生命周期。

        分代垃圾算法中,年轻代一般选择复制算法效率高,不会产生内存碎片,老年代可以选择标记-清除算法或者标记-整理算法。

3.FullGC:

      FullGC 是 Java虚拟机(JVM)中垃圾收集过程的一种情况。它是一个较为昂贵的操作,会对整个堆(包括年轻代和老年代)进行垃圾回收,通常会导致较长的"Stop-The-World"(STW)暂停时间,因此开发者往往会尽量避免频繁的Full GC。

   3.1 触发条件:

        (1).老年代空间不足:

        当老年代(Old Generation)空间不足时,需要触发Full GC来回收老年代中的垃圾对象

        (2).永久代(PermGen)或元空间(Metaspace)空间不足:

        在JDK 8之前,永久代存储类的元数据,PermGen满了可能会触发Full GC。
        在JDK 8及之后,永久代被替换为元空间(Metaspace),如果元空间满了也会触发Full GC。

        (3).显式触发:

        通过调用 System.gc() 方法显式触发垃圾回收。虽然调用该方法只是向 JVM 发出建议,但在某些情况下,JVM 可能会选择执行 Full GC。

   3.2 Full GC总结:

        Full GC 是一种较为耗时的操作,因为它需要扫描和回收整个堆内存。在 Full GC 过程中,
应用程序的执行通常会暂停,这可能会导致较长的停顿时间(长时间的停顿会影响应用程序的响应性能)。 
        为了避免频繁的 Full GC,通常采取一些优化措施,如合理设置堆大小、调优垃圾回收参数、减少对象的创建和存活时间等。

4.垃圾回收器:

        (1).Serial GC:

  • 单线程垃圾回收器,适用于单处理器环境。
  • 简单且低开销,适合小型应用程序或低内存环境。
  • 停止所有应用线程(Stop-the-World)进行垃圾回收,导致停顿时间较长。

        (2).Parallel GC(Throughput Collector)

  • 多线程垃圾回收器,适合多处理器环境。
  • 主要目标是提高吞吐量(减少垃圾回收的总时间)。
  • 停止应用线程,但垃圾回收期间并行工作,适合批处理和后台任务。

        (3).CMS(Concurrent Mark-Sweep) GC

  • 低停顿时间垃圾回收器,适合响应时间敏感的应用程序。
  • 在标记和清除阶段与应用线程并发工作,但会产生内存碎片。
  • 逐步被G1 GC取代。

        (4).G1 GC(Garbage-First Garbage Collector)

  • 面向大内存、多处理器的应用程序设计,适合大多数应用。
  • 分区化的内存管理,能有效减少内存碎片,提供可预测的停顿时间。
  • 自动选择年轻代和老年代的内存回收区域。

        (5).ZGC(Z Garbage Collector):

  • 专为低延迟设计,停顿时间通常低于10毫秒。
  • 适用于高吞吐量、高并发的应用,能处理大规模的堆(最大可达TB级)。
  • 采用染色指针和加载屏障技术来实现并发垃圾回收。

        (5).Shenandoah GC:

  • 类似于ZGC的低停顿垃圾回收器。
  • 采用并发压缩算法,最大化减少停顿时间。
  • 更适用于大堆内存和响应时间要求高的应用程序。

垃圾回收器组合:

        JDK8及之前:

        ParNew +CMS(关注暂停时间),

        Parallel Scavenge + Parallel Old (关注吞吐量),

        G1(JDK8之前不建议,.较大堆并且关注暂停时间)

         JDK9之后:G1(默认)

        从JDK9之后,由于G1日趋成熟,JDK默认的垃圾回收器已经修改为G1,所以强烈建议在生产环境上使用G1。
如果对低延迟有较高的要求,可以使用Shenandoah或者ZGC。

  • 13
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值