当前位置: 首页 > article >正文

《JVM第8课》垃圾回收算法

文章目录

    • 1.标记算法
      • 1.1 引用计数法
      • 1.2 可达性分析法
    • 2.回收算法
      • 2.1 标记-清除算法(Mark-Sweep)
      • 2.2 复制算法(Coping)
      • 2.3 标记-整理算法(Mark-Compact)
    • 3.三种垃圾回收算法的对比

为什么要进行垃圾回收?

垃圾是指 JVM 中没有任何引用指向它的对象,如果不及时清理这些垃圾对象,那么它就会一直占用内存,如果垃圾对象越来越多,就会出现OOM了。

要判断对象是否是垃圾对象有两种方式,一、引用计数法。二、可达性分析法。

而要清除垃圾对象有三种常用方式,一、标记-清除算法。二、复制算法。三、标记-整理算法。

1.标记算法

要清除垃圾首先要找到垃圾,JVM是通过什么算法找到堆中的垃圾对象的呢?

1.1 引用计数法

每个对象都保存一个引用计数器属性,用于记录对象被引用的次数。如果计数器为 0 则表示是垃圾对象。

优点:原理简单,计数器为 0 则表示是垃圾对象。

缺点

  1. 需要额外的空间和时间来维护引用计数。
  2. (严重) 无法处理循环引用的问题。

循环引用就是A对象里有个B对象的属性,B对象里有个A对象的属性,这样的话A和B的引用计数器都会等于1,永远不会被回收。所以引用计数法很少使用!!!

1.2 可达性分析法

可达性分析法会以GC Roots作为起始点,然后一层一层的去寻找引用的对象,被找到的对象就是存活对象,无法到达的对象就是垃圾对象。

在这里插入图片描述

GC Roots是一组引用,基本常用的包括:

  • 线程的虚拟机栈的栈帧中的方法参数、局部变量所对应的对象引用
  • 线程的本地方法栈的栈帧中的方法参数、局部变量所对应的对象引用
  • 方法区中保存的类信息中静态属性、常量属性所对应的对象引用

2.回收算法

2.1 标记-清除算法(Mark-Sweep)

既然我们已经能够找到哪些是垃圾对象,那么我们该怎么去回收这些垃圾对象呢?这里又涉及到一些算法,首先比较简单的就是标记-清除算法。

标记-清除算法是一种非常基础的垃圾回收算法,针对某块内存空间,比如新生代、老年代,如果可用内存不足后,就会STW(暂停用户线程的执行),然后执行算法进行垃圾回收:

  1. 标记阶段:从 GC Roots 开始遍历,找到可达对象,并在对象头中进行记录。
  2. 清除阶段:堆内存空间进行线性遍历,如果发现对象头中没有记录是可达对象,则回收它。

在这里插入图片描述

缺点:

  1. 效率不高,和后面讲的算法来比效率确实不高。
  2. 内存碎片,对象被清除后会留下一块一块的小内存,由于这些小内存不是连续的,所以很可能不够存储新来的大对象。

优点:

  1. 思路简单。

2.2 复制算法(Coping)

复制算法的思想就是空间换时间。它将内存空间分为两块,每次只使用一块,在进行垃圾回收时,会首先STW,然后遍历将可达对象复制到另外没有被使用的内存块中,然后再将当前内存块标记为可重用,后续再按相同的流程进行垃圾回收,两块内存交换着来。这也是为什么新生代中会有 S1 和 S2 两块内存区域的原因。

在这里插入图片描述

复制算法只遍历一次,在遍历的同时就把可达对象复制到另一块内存中,而标记-清除算法需要遍历两次,标记和清除各一次。

优点:

  1. 只遍历一次,效率高。
  2. 不会出现内存碎片。

缺点:

  1. 需要更多的内存,始终有一半的空闲内存。
  2. 对象复制后,对象的内存地址发生了变化,需要额外的时间修改栈帧中记录的引用地址。
  3. 如果可达对象比较多,垃圾对象比较少,那么复制算法的效率就会比较低,所以新生代特别适合复制算法,因为新生代的垃圾对象比较多(但也不绝对)。

2.3 标记-整理算法(Mark-Compact)

第一阶段和标记-清除算法一致,也是标记可达对象,也会STW。

第二阶段将所有存活对象移动到内存的一端。

最后清理边界外的所有空间

在这里插入图片描述

优点:

  1. 不会出现内存碎片。
  2. 也不需要利用额外的内存空间。

缺点:

  1. 效率要低于标记清除算法、复制算法。
  2. 也需要修改栈帧中的引用地址。

3.三种垃圾回收算法的对比

标记-清除标记-整理复制
速度中等最慢最快
空间开销少(有碎片)少(无碎片)最多
移动对象

http://www.kler.cn/a/387502.html

相关文章:

  • 使用ookii-dialogs-wpf在WPF选择文件夹时能输入路径
  • 问:MySQL主从同步的机制梳理?
  • 从0开始机器学习--Day23--支持向量机
  • OpenEuler 下 Docker 安装、配置与测试实例
  • Linux入门:环境变量与进程地址空间
  • wordpress实用功能A5资源网同款 隐藏下载框 支付框 需要登录才能查看隐藏的内容
  • 软考:论DevOps
  • 编码算法笔记(base64,url编码等)
  • iphone怎么删除重复的照片的新策略
  • Elasticsearch里的索引index是什么概念?(ChatGPT回答)
  • 机器学习 - 为 Jupyter Notebook 安装新的 Kernel
  • ArcGIS软件之“计算面积几何”地图制作
  • 人工智能技术的应用前景及未来发展:改变工作与生活的力量
  • opencv 中 threshold 函数作用
  • 万字长文解读深度学习——GPT、BERT、T5
  • Ubuntu 22.04安装ROS 1教程汇总
  • 多线程---线程池
  • # filezilla连接 虚拟机ubuntu系统出错“尝试连接 ECONNREFUSED - 连接被服务器拒绝, 失败,无法连接服务器”解决方案
  • SQL,力扣题目1127, 用户购买平台
  • 本地 Hadoop 开发环境搭建详解
  • MTK6833/MT6833(天玑700)安卓核心板_联发科5G智能通讯模块安卓主板定制
  • 如何在下载我上传的数据时自动设置 Content-Type
  • Mac brew安装软件镜像加速
  • Android的Handler
  • 手写Golang泛型栈和队列的库函数
  • 万字长文解读深度学习——卷积神经网络CNN