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

秋招突击——8/15——知识补充——垃圾回收机制

文章目录

    • 引言
    • 正文
      • 指针引用
      • 可达性分析算法
      • 垃圾回收算法
        • 标记清除算法
        • 标记整理算法
        • 复制
        • 分代收集
      • 垃圾收集器
        • Serial收集器
        • ParNew并行收集器
        • Parallel Scavenge吞吐量优先收集器
        • Serial Old老年代收集器
        • Parallel old收集器
        • CMS收集器
        • G1收集器(Garbage First垃圾优先)
    • 总结

引言

  • 上次面试腾讯,让我说了一下垃圾回收机制,虽然大概都说出来了,但是觉得还是有不够详细,今天好好整理一下,下次不会这么狼狈了!

正文

指针引用

  • Java中对象的访问是需要通过引用进行判断的,引用主要分为其中,按照强度递减分别是:强软弱虚

    • 强引用
      • 通过new创建的对象,直接用=赋值,如果还存在强引用,垃圾回收器绝对不会回收他
    • 软件引用
      • 需要使用SoftReference进行声明
      • 如果内存不够了,要报异常了,这里就要的优先回收软引用
      • 用于对象缓存
    Obj obj = new Obj();
    SoftReference<Obj> sr = new SoftReference<Obj>(obj)
    
    • 弱引用
      • 描述非必须的对象,当一个对象只有弱引用,只要发生GC,一定会被回收
    Obj obj = new Obj();
    WeakReference<Obj> sr = new WeakReference<Obj>(obj)
    
    • 虚引用
      • 最弱的引用,形同虚设
      • 仅仅是当前对象被回收了,我能收到通知

可达性分析算法

  • 通过一系列GC Root的根对象作为起始节点,然后根据引用关系向下搜索,搜索走过的路径就是引用链。

    • GC Root不可达,说明对象不再被使用
    • GC Root可达,说明对象仍旧在使用
  • 固定为GC Root的对象有以下几种

    • 虚拟栈中引用的对象
    • 在方法区,类静态属性引用的对象
    • 在方法区,常量引用的对象
    • 在本地方法栈中Native方法引用的对象
    • Java虚拟机内部的引用
    • 同步锁持有的对象

垃圾回收算法

标记清除算法
  • 找出所有对象,将存活对象进行标记,然后清理掉未标记的对象,结束。
    在这里插入图片描述
标记整理算法
  • 首先找出所有对象,将存活对象进行标记,然后将存活对象整理一端,将内存区域直接清除掉
    在这里插入图片描述
复制
  • 将内存划分为大小相等的两块,每次只使用其中一块,当这一块内存用完了,就将存活对象复制到另外一块上,然后再将使用过的内存空间进行一次清理
    在这里插入图片描述
分代收集
  • 根据对象的存活周期将内存划分为几块,不同块采用不同的收集算法。
  • 一般分为新生代和老年代,
    • 新生代
      • 绝大多数的对象都是活不过一次垃圾回收
      • 使用复制算法
    • 老年代
      • 大多数是熬过了很多次垃圾回收过程的对象。
      • 标记清除 或者 标记整理算法

垃圾收集器

  • 目前常用的hotpot虚拟机支持其中垃圾收集器,可以混用。
    在这里插入图片描述
Serial收集器
  • 基本流程
    • 暂停所有的工作线程,专门进行垃圾回收
  • 针对对象
    • 新生代
  • 算法
    • 复制算法
ParNew并行收集器
  • 多线程版的Serial收集器
  • 基本流程
    • 暂停所有工作线程,使用多线程进行垃圾回收
  • 针对对象
    • 新生代
  • 算法
    • 复制算法
Parallel Scavenge吞吐量优先收集器
  • 多线程垃圾收集器,尽量压缩垃圾收集时,用户线程的停顿时间

  • 基本流程

    • 暂停所有工作线程,使用多线程进行垃圾回收
  • 针对对象

    • 新生代
  • 算法

    • 复制算法
  • 注意

    • 需要控制最大垃圾收集停顿时间
    • 设置吞吐量大小
Serial Old老年代收集器
  • Serial收集器的老年版,使用标记-整理算法,提供客户端模式下使用
  • 基本流程
    • 暂停所有工作线程,使用多线程进行垃圾回收
  • 针对对象
    • 老年代
  • 算法
    • 标记整理算法
Parallel old收集器
  • 多线程垃圾收集器,尽量压缩垃圾收集时,用户线程的停顿时间

  • 基本流程

    • 暂停所有工作线程,使用多线程进行垃圾回收
  • 针对对象

    • 老年代
  • 算法

    • 复制算法
  • 注意

    • 应用于处理器资源较为稀缺的场合,考虑使用Parallel Scavenge 和 Parallel Old一块使用
CMS收集器
  • 追求最短停顿时间的垃圾收集器

  • 基本流程

    • 初始标记
      • 停下所有线程,仅仅标记一下GC Root能够关联的对象
    • 并发标记
      • 用户线程并行,进行GC Roots Tracing,耗时最长
    • 重新标记
      • 修正并发期间因为程序调用导致的标记变动,停下所有工作线程,耗时较短
    • 并发清除
      • 用户线程并行,清除掉死亡对象
  • 总结

    • 吞吐量低,但是停顿时间少,完成垃圾回收时间长,但是是并行的
    • 使用标记清除算法,内存空间不连续,大量的空间碎片
G1收集器(Garbage First垃圾优先)
  • 将内存进行分区,然后进行回收价值和成本排序,价值越高成本越低的区块优先回收。

  • 特性和问题总结:

    • 将整个堆分成大小相同的Region区域,每一个都是Region都可能是新生代、老年代、Eden空间和Survivor空间
    • G1每次收集的时候,只会收集部分Region,每次收集时,会先估算每一个小块存活对象的总数,回收垃圾最多的小块会先被收集
      • 对于跨Region的引用对象,使用记忆集解决
      • 并发标记阶段如何保证收集县城和用户线程互不干扰的运行
        • 回收过程中改变对象引用关系:通过原始快照SATB算法实现
        • 回收过程中创建新对象:使用单独的分区和指针TAMS保存新创建的对象
  • 四个步骤

    • 初始标记
      • 仅仅标记一下GC Root能够关联的对象(停顿一下)
    • 并发标记
      • 进行可达性分析,完成对象图扫描,判断存活对象和可回收对象
      • 处理STAB记录的是否有引用变动的对象
    • 最终标记
      • 暂时停顿,查看处理并发阶段结束后少量的SATB记录
    • 筛选回收
      • 根据统计的回收价值和成本并排序,筛选region进行回收
      • 使用标记复制的算法实现

总结

  • 这里是粗浅的理解,后续会在有补充,有很多问题都没有解决,包括怎么进行GC调优呀等等,都没有看!

http://www.mrgr.cn/news/689.html

相关文章:

  • Aria2@RPC下载@Alist批量下载
  • JMeter进阶技巧:参数化与数据驱动测试
  • 基于微信小程序的课堂考勤系统的设计与实现(论文+源码)_kaic
  • Vue 添加 dayjs 方便日期操作
  • 机器学习中的多模态学习
  • 【C++】C++11新增特性
  • 【网络】网络基础概念背景TCP/IP 五层模型跨网络传输详解
  • C/C++实现蓝屏2.0
  • 如何建立一个既能快速记录又易于回顾的笔记系统?
  • C语言第20天笔记
  • Unity游戏开发002
  • [Qt][对话框][下]详细讲解
  • 对比state和props的区别?
  • 在 C# 中使用 AutoMapper 进行对象映射
  • C++第十一弹 -- STL之List的剖析与使用
  • 通过kuboard界面配置ingress
  • 使用 onBeforeRouteLeave 组合式函数提升应用的用户体验
  • 结合GPT与Python实现端口检测工具(含多线程)
  • 【计算机网络】CIDR无分类编址知识学习
  • HarmonyOS开发案例:创建全局自定义组件复用池-BuilderNode