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

JVM 垃圾回收之垃圾回收算法

一、既然提到了垃圾回收那么我们首先要明确的是什么是垃圾

垃圾的概念就是指程序运行过程中没有任何指针指向的对象,那么这样的对象就是需要被回收的垃圾

如果不能及时的对这些内存中的垃圾进行回收,那么这些垃圾就会一直占用空间到程序结束,被保留的空间无法被其他对象使用,从而可能导致内存溢出

二、为什么需要GC????

  • 一个基本的认知就是高级程序设计语言如果不进行垃圾回收那么最后一定会造成内存溢出。那么为了避免这样的现象就一定需要有垃圾回收机制进行垃圾清理。
  • 而且,除了释放没用的对象外还可以整理 JVM 中碎片的内存区域,将不规整的小碎片区域进行整理,为后来可能出现的大对象预留空间
  • 随着业务越来越庞大,代码越来越复杂,用户越来越多,传统的 STW 的垃圾回收方式已经跟不上需求,必须对传统的垃圾回收方式进行改进

三、主要对那些内存区域进行 GC

垃圾回收器可以对 JVM 管理的所有内存区域进行垃圾回收,其中 堆区域是垃圾回收的重点
从次数上讲 应该是频繁的收集 young 区,较少回收 old 区,基本不动 Perm 区

四、这就到了这次的重头戏-——垃圾回收算法

4.1 判别阶段的算法
4.1.1 引用计数法

什么是引用计数? 对于一个对象 A ,如果有其他的任何一个对象引用了 A ,则 A 的引用计数器加 1 ,当应用失效时,则该对象的引用计数器减 1 ,只要该对象的引用计数器为 0 则证明没有其他对象引用该对象,即当前对象引用失效,可以进行回收

优点? 实现简单,垃圾对象便于标识,判定效率高,回收没有延迟性
缺点?

  • 存在循环引用问题,可能会出现两个孤岛彼此相连无法回收的问题(主要问题)
  • 它需要单独存储计数器,增加了空间开销
  • 每次赋值都需要进行计数器的更新,增加了时间开销

就想用这个算法怎么办????
那么就要解决主要矛盾——循环引用问题的解决:Python就使用了引用计数的方法进行垃圾回收,那么 Python 是怎么解决的呢?

  • 首先就是使用手动解除,这很好理解,就是在合适的时候,解除引用关系
  • 其次就是使用弱引用(weakref)

关于 Python 这作者只知道这些,余下的需要读者去进行补充

4.1.2 可达性分析算法

原理与基本实现思路:简单来说就是将对象之间的引用关系看成图,选定活动的对象作为 GC Roots ,然后跟踪引用链条,如果一个对象和 GC Roots 之间不可达,也就是不存在引用链条,那么即可认为是可回收对象。

基本思路:

  • 可达性分析算法是以根对象集合(GC Roots)为起始点,按照从上至下的方式搜索被根对象集合所连接的目标对象是否可达。
  • 使用可达性分析算法后,内存中的存活对象都会被根对象集合直接或间接连接着,搜索所走过的路径称为引用链(Reference Chain)
  • 如果目标对象没有任何引用链相连,则是不可达的,就意味着该对象己经死亡,可以标记为垃圾对象。
  • 在可达性分析算法中,只有能够被根对象集合直接或者间接连接的对象才是存活对象。

目前,这种垃圾标记算法比较常用

优点:实现简单,执行高效,有效解决循环引用的问题,可以防止内存泄漏

什么样的对象可以被认为是 Gc Roots ?

  • 虚拟机栈中引用的对象
    • 比如:各个线程被调用的方法中使用到的参数、局部变量等。
  • 本地方法栈内JNI(通常说的本地方法)引用的对象
  • 类静态属性引用的对象
    • 比如:Java类的引用类型静态变量
  • 方法区中常量引用的对象
    • 比如:字符串常量池(String Table)里的引用
  • 所有被同步锁synchronized持有的对象
  • Java虚拟机内部的引用。
    • 基本数据类型对应的Class对象,一些常驻的异常对象(如:NullPointerException、OutOfMemoryError),系统类加载器。
  • 反映java虚拟机内部情况的JMXBean、JVMTI中注册的回调、本地代码缓存等

注意:
如果要使用可达性分析算法来判断内存是否可回收,那么分析工作必须在一个能保障一致性的快照中进行。不满足这个条件的话分析结果的准确性就无法保证。
这也是导致 GC 必须进行 STW 的原因,即使是号称没有停顿的 CMS 收集器在枚举根节点时也会发生停顿。

终于又让我水完了一篇文章,累鼠鼠鼠了,由于此篇文章篇幅已经很长,JVM 又很枯燥,所以就将回收算法中真正进行垃圾清除阶段的算法放在下一篇文章啦!!!!!!!


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

相关文章:

  • 文件操作(File类)
  • Day50 图论part01
  • 一区牛顿-拉夫逊算法+分解+深度学习!VMD-NRBO-Transformer-GRU多变量时间序列光伏功率预测
  • 【ETCD】【源码阅读】深入分析 storeTxnWrite.Put方法源码
  • Marin说PCB之POC电路layout设计仿真案例---06
  • javaFX.(蜜雪冰城点餐小程序)MySQL数据库
  • Android Vendor Overlay机制
  • 【机器学习】【集成学习——决策树、随机森林】从零起步:掌握决策树、随机森林与GBDT的机器学习之旅
  • Qt之样式表使用(十一)
  • STM32中ADC模数转换器
  • 动手学深度学习11.1. 优化和深度学习-笔记练习(PyTorch)
  • 嵌入式驱动开发详解17(CAN驱动开发)
  • 在 Linux 下,将 tar 包打包成二进制程序
  • 【系统方案资料集】工业互联网数字中台解决方案,产业互联网数据中台解决方案,数据中台整体建设方案(Word,PPT)
  • Centos创建共享文件夹拉取文件
  • 使用Element-UI transfer穿梭框在屏幕下鼠标悬浮显示完整信息
  • 如何在 Ubuntu 22.04 上安装 MySQL
  • 《Posterior Collapse and Latent Variable Non-identifiability》
  • 【数据结构】平衡二叉树
  • 【Canvas与仪表盘】铝圈蓝底汽车速度仪表盘(可用键盘按键调节速度值)
  • 初学stm32 --- 外部中断
  • C语言与C++与Python与Java的差别
  • TCA9555芯片手册解读(6)
  • 2024年12月陪玩系统-仿东郊到家约玩系统是一种新兴的线上预约线下社交、陪伴系统分享-优雅草央千澈-附带搭建教程
  • upload-labs(1-19关)通关攻略
  • Vue零基础教程|从前端框架到GIS开发系列课程(六)组合式API