JVM垃圾回收

在JVM中,垃圾回收主要指的是回收堆(Heap)内存中不再被使用的对象所占用的空间。JVM通过垃圾回收机制自动执行这一过程,以确保有效地利用内存资源。

垃圾判断方式

引用计数法

给对象添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1。任何时刻计数器为0的对象就是不可能再被使用的。

// 优点:简单,效率高
// 缺点:很难解决对象循环依赖的问题.
例:
public class ConutingGC{
  Object instance = null;
  public void test(){
  ConutingGC A =  new  ConutingGC();
  ConutingGC B =  new  ConutingGC();
  A.instance = B;
  B.instance = A;
  A = null;
  B = null;
  }
}  

可达性算法

将GC Roots 对象作为起点,从这些节点开始向下搜索引用的对象,找到的对象都标记为非垃圾对象,其余为标记的对象都是垃圾对象.
注:GC Roots根节点集合:线程栈的本地变量、静态变量、本地方法栈道变量等等.

// GC Roots对象
// 1.虚拟机栈中引用的对象
public class StackReference {
    public void localVariableReference() {
        // localObj是一个GC Roots,因为它是一个局部变量。
        Object localObj = new Object(); 
    }
}

// 2.方法区中的类静态属性引用的对象
public class StaticFieldReference {
	// staticObj是一个GC Roots,因为它是一个静态变量。
    private static Object staticObj = new Object(); 
}

// 3.方法区中常量引用的对象
public class ConstantReference {
    public void constantStringReference() {
        // 这个字符串常量是一个GC Roots。
        String constantString = "Hello, World"; 
    }
}

// 4.本地方法栈中JNI引用的对象
public class NativeReference {
	// 假设这个本地方法中引用了某个对象。
    private native void nativeMethod(); 
}

// 5.被同步锁持有的对象
public class SynchronizedReference {
    public void synchronizedReference() {
        Object lockObj = new Object();
        synchronized(lockObj) {
            // 在这个同步块中,lockObj是一个GC Roots。
        }
    }
}

垃圾回收算法

垃圾回收(GC)算法是自动内存管理的核心,旨在识别和回收不再使用的内存空间。以下是一些主要的垃圾回收算法.

标记-清除(Mark-Sweep)

在这里插入图片描述

// 原理
该算法分为'标记''清除'两个阶段。
首先,从GC Roots开始遍历所有可达对象,并标记它们。
然后,在清除阶段,回收所有未被标记的对象所占用的内存
// 优点
实现简单,直接回收不再使用的对象。
// 缺点
效率问题:标记和清除过程的效率不高.
空间问题:会产生大量内存碎片.

标记-整理(Mark-Compact)

在这里插入图片描述

// 原理
该算法在标记-清除的基础上增加了整理过程。在标记阶段后,将所有存活的对象向一端移动,然后清理边界以外的内存。
// 优点
解决了标记-清除算法中的内存碎片问题
// 缺点
移动对象需要更多的时间,可能会导致较长的停顿时间。

复制算法

在这里插入图片描述

// 原理
将可用内存划分为两块,每次只使用其中一块。
在垃圾回收时,将当前使用区域中的存活对象复制到另一块区域中,然后清理掉当前区域的所有内存。
// 优点
简单且高效,不会产生内存碎片。
// 缺点
内存利用率低,因为任何时候只有一半的内存是可用的。

垃圾收集器

  • Serial收集器
    类型 :单线程收集器
    算法:标记-清除-整理
    特点:简单而高效(在单线程环境下).在进行垃圾回收时,需要暂停其他所有的工作线程(“Stop-The-World”)
    适用场景:适合单核处理器或小内存环境,以及客户端模式下的桌面应用

  • Parallel收集器(Parallel GC)
    类型 :并行的多线程收集器
    算法:标记-清除-整理
    特点:在垃圾回收阶段,多个垃圾收集线程并行工作,提高垃圾回收效率。同样采用"Stop-The-World"机制。
    适用场景:注重吞吐量以及CPU资源充足的多核服务器端应用。

  • CMS收集器(Concurrent Mark Sweep)
    类型 :并发的垃圾收集器
    算法:标记-清除
    特点:并发收集、低停顿。分为四个主要阶段:初始标记、并发标记、重新标记、并发清除。
    适用场景:适合互联网站或者B/S系统的服务器上,这类应用尤其需要更短的垃圾收集停顿时间。

  • G1收集器(Garbage-First)
    类型 :并发的垃圾收集器
    算法:标记-整理加复制
    特点:将堆内存分割成多个大小相等的独立区域(Region),通过优先回收价值最大的Region来控制停顿时间(Garbage-First)
    适用场景:面向服务端应用,尤其是多核服务器环境中,需要满足大内存、多核CPU的场景下的低停顿时间要求。

  • ZGC(Z Garbage Collector)
    类型 :可伸缩的低延迟垃圾收集器(JDK 11引入)
    算法:基于Region的标记-整理算法
    特点:支持多达数TB的堆内存,停顿时间不会随着堆或者活跃对象的增长而增长,停顿时间小于10ms。
    适用场景:适用于需要极低停顿时间且具有大内存需求的应用。

CMS收集器(Concurrent Mark Sweep)

CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。它非常注重用户体验,它第一次实现了让垃圾收集线程与用户线程同时工作.它采用的算法是标记清除.
在这里插入图片描述

// 1.初始标记
暂停所有的其他线程(stw),并记录下GC Roots直接能引用的对象,速度很快.(如果不stw,程序做不完)
// 2.并发标记
并发标记阶段就是从GC Roots的直接关联对象开始遍历整个对象图的过程,这个过程耗时较长但是不需要停顿用户线程,可以与垃圾收集线程一起并发运行.
因为用户程序继续运行,可能会有导致已经标记过的对象状态发生改变.占用时间最长。
// 3.重新标记
重新标记阶段就是为了修正并发标记期间因为用户程序继续运行而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间一般会比初始阶段的时间稍长,远远比并发阶段时间短.主要用三色标记里的增量更新算法做重新标记.
// 4.并发清理
开启用户线程,同时GC线程开始对为标记的区域做清理.这个阶段如果有新增对象会被标记为黑色不做任何处理.
// 5.并发重置
重置本次GC过程中的标记数据.

// 总结CMS
a.CMS收集器的主要目标是减少垃圾回收时的停顿时间,使得应用程序的响应更加及时.
b.除了初始标记和重新标记阶段,其他阶段CMS收集器都能与应用线程并发执行。
c.由于在并发标记和并发清除阶段,应用线程仍在运行,可能会产生新的垃圾,这部分垃圾被称为'浮动垃圾',直到下一次GC时才会被清理。

在并发标记的过程中,因为标记期间应用线程还在继续跑,对象间的引用可能发生变化,多标和漏标的情况就有可能发生。

三色标记

三色标记算法是把Gc roots可达性分析遍历对象过程中遇到的对象, 按照“是否访问过”这个条件标记成以下三种颜色

// 白色
表示对象尚未被垃圾收集器访问过
// 黑色
表示对象已经被垃圾收集器访问过,且这个对象的所有引用都已经扫描过,无须重新扫描
// 灰色
表示对象已经被垃圾收集器访问过, 但这个对象上至少存在一个引用还没有被扫描过

多标问题
在这里插入图片描述

// 解决
多标就是浮动垃圾,下一次gc清除就可以.

漏标问题
在这里插入图片描述

// 解决
// 1.增量更新
当黑色对象插入新的指向白色对象的引用关系时, 就将这个新插入的引用记录下来, 等并发扫描结束之后, 再将这些记录过的引用关系中的黑色对象为根, 重新扫描一次。 这可以简化理解为, 黑色对象一旦新插入了指向白色对象的引用之后, 它就变回灰色对象了。
// 2.原始快照
就是当灰色对象要删除指向白色对象的引用关系时, 就将这个要删除的引用记录下来, 在并发扫描结束之后, 再将这些记录过的引用关系中的灰色对象为根, 重新扫描一次,这样就能扫描到白色的对象,将白色对象直接标记为黑色目的就是让这种对象在本轮gc清理中能存活下来,待下一轮gc的时候重新扫描,这个对象也有可能是浮动垃圾.
  • 24
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值