JVM的垃圾回收机制

目录

GC的工作范围

谁是垃圾

怎么判断,某个对象是否有引用指向捏?

(1)引用计数

缺陷

释放垃圾的策略

(1)标记清除(不实用)

(2)复制算法

(3)标记整理

分代回收(中和方案)


垃圾回收机制GC是java提供的对于内存自动回收的机制,相对于C/C++的手动回收是方便不少的,但是一切的方便都是需要代价的,GC需要消耗额外的系统资源,而且存在非常影响执行效率的STW(stop the world)问题,触发GC的时候,就可能一瞬间把系统负载拉满,这些是C/C++无法容忍的。

GC的工作范围

GC回收的是”内存“,更准确的说是”对象“,回收的是”堆上的内存“。

(1)程序计数器:不需要额外回收,线程销毁,自然就回收了

(2)栈:不需要额外回收,线程销毁,自然回收了

(3)元数据区:一般也不需要,都是加载类,很少卸载类

(4)堆:GC的主要工作区

谁是垃圾

GC是自动回收的,那么回收怎么知道这个对象是垃圾捏?

一个对象,什么时候创建,时机往往是明确的。 但是什么时候不再使用, 时机往往是模糊的。在编程中,一定要确保,代码中使用的每个对象,都得是有效的,,万不要出现"提前释放"的情况
宁可放过,也不能错杀~~
因此判定一个对象是否是垃圾,判定方式是比较保守的~~

此处引入了非常"保守"的做法,一定不会误判的做法(可能会释放的不及时),判定某个对象,是否存在引用指向它

例如:
Test t = new Test();
t=null;

使用对象,都是通过引用的方式来使用的,如果没有引用指向这个对象,意味着这个对象注定无法再代码中被使用。将t指向为null,此时new Test()的对象就没有引用指向了,此时这个对象就可以认为是垃圾了。

怎么判断,某个对象是否有引用指向捏?

介绍两种方法

(1)引用计数

为对象的本体加一个计数器,对象每被引用一次,计数器就+1,对象每少一个引用,计数器就-1,当计数器为0时,此时对象就是垃圾了

缺陷

(1)消耗额外的内存空间:如果你的对象比较大,浪费的空间还好(有1w块钱,花1块钱在计数器上就还行),对象比较小,空间占用就多了(只有10块钱,花一块钱在计数器上),并且对象数目越多,空间浪费的就多

(2)存在”循环引用“的问题,代码解释

public class A {
    private B b;

    public void setB(B b) {
        this.b = b;
    }
}

public class B {
    private A a;

    public void setA(A a) {
        this.a = a;
    }
}

public class Main {
    public static void main(String[] args) {
        A objA = new A();    //A的计数器+1
        B objB = new B();    //B的计数器+1

        objA.setB(objB);    //A中引用了B,B的计数器再+1
        objB.setA(objA);    //B中引用了A,A的计数器再+1

        objA=null;        //A的计数器-1
        objB=null;        //B的计数器-1

    }
}

在上述情况下,即使没有任何其他对象引用A和B,它们的引用计数也永远不会变为零,因为它们之间互相引用,计数器都为1,判定不是垃圾,导致无法释放内存,但是外部代码也无法访问到这两对象!!!

注意:引用计数不是JVM采取的方案,而是Python/PHP的方案

(2)可达性分析(是JVM采取的方案)

这个方案解决了空间上的问题,也解决了循环引用的问题,但是也需要付出代价,时间上的代价。

JVM把对象之间的引用关系,理解成一共”树形结构“,JVM会不停的遍历这样的结构,把所有能够遍历访问到的对象标记成”可达“,剩下的就是”不可达“

举例:简单的伪代码帮助理解

class Node{
    Node left;
    Node right;
}
Node build(){
    Node a = new Node();
    Node b = new Node();
    Node c = new Node();
    Node d = new Node();
    Node e = new Node();
    Node f = new Node();
    Node g = new Node();
}
a.left = b;
a.right = c;
b.left = d;
b.right = e;
e.left = g;
c.right = f;

return a;
}

Node root = build();    //此处只有一共引用,通过这个引用就能访问到树上所有节点对象

上述代码的树状图如下(简画)

a的左边是b,右边是c,b的左边是d,右边是e,c的右边是f,e的右边是g

在上述树状图中,如果a.right=null,此时c就不可达了,同时f也不可达了,访问不到就标记成垃圾被回收,如果写了root=null,就是要把树上所有的对象都干掉

java代码中可能会有很多棵这样的树,JVM就会周期性的堆这所有的树进行遍历,不停的标记可达,也不停的把不可达的对象干掉

释放垃圾的策略

(1)标记清除(不实用)

直接把标记为垃圾的对象对应的内存释放掉,简单粗暴

这样的做法会存在"内存碎片"问题,空闲内存被分成一个个的碎片了,后续很难申请到大的内存!

(2)复制算法

比如上图,要释放 1,3,5, 保留 2,4,不会直接释放1,3,5 的内存,而是把2,4拷贝到另外一块空间中,让后将原来的1,2,3,4,5的空间全部释放,这样就解决了内存碎片问题

缺点:浪费空间太多,如果要保留的空间比较多,复制的时间开销也不少

(3)标记整理

标记整理算法首先从一组根对象出发,通过可达性分析,标记所有活动对象。在标记完成后,所有被标记的存活对象会被移动到内存空间的一端,形成一个紧凑的连续区域,而未被标记的对象则被视为垃圾对象。然后,垃圾对象所占用的内存空间会被释放出来,形成一个连续的、空闲的内存区域。最后,整个内存空间会被整理,将存活对象移动到一端,释放的空闲内存空间集中到另一端,从而减少内存碎片化,提高内存的利用率

类似于顺序表中删除中间元素

上述三种方案只是铺垫,JVM中实际的方案,是综合上述的方案,分代回收

分代回收(中和方案)

分情况讨论,根据不同的场景/特点,选择合适的方案~~

根据对象的年龄来讨论的,GC 有一组线程,周期性扫描。某个对象经历了一轮 GC 之后,还是存在,没有成为垃圾,年龄 +1。
可以这么理解:"要g 早g 了"既然没有早g,说明这个对象,有东西,还能继续存在!!!

把新创建的对象,放到伊甸区中,
伊甸区中,大部分的对象,生命周期都是比较短的,第一轮 GC 到达的时候,就会成为垃圾只有少数对象能活过第一轮 GC 

伊甸区 ->生存区
通过复制算法。(由于存活对象很少,复制开销也很低,生存区空间也不必很大)

生存区 ->另一个生存区
通过复制算法,没经过一轮 GC,生存区中都会淘汰掉一批对象,剩下的通过复制算法,进入到另一个生存区(进入另一个生存区的还有从伊甸区进来的对象)
存活下来的对象, 年龄 +1

生存区 ->老年区        某些对象,经历了很多轮 GC,都没有成为垃圾,就会复制到老年代。老年代的对象,也是需要进行 GC 的,但是老年代的对象生命周期都比较常, 就可以降低 GC 扫描的频率

上述过程是”分代回收“的基本逻辑

对象 伊甸区 ->生存区 ->生存区 ->老年代 复制算法对象

在老年代中,通过标记-整理(搬运) 来进行回收~~

感谢支持,有帮助点个赞 😜

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/670412.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

公网IP地址如何查询?

公网IP地址是指在互联网中可以被全球范围内的设备访问的IP地址。在网络通信中,公网IP地址扮演着重要的角色,它可以标识设备在互联网中的位置。查询公网IP地址是一种常见的网络管理需求,因为它能够提供网络设备的准确位置信息,方便…

首套真题解析!安徽211难度适中!两门课!

这个系列会分享名校真题。并做详细解析!此为24年第一套! 今天分享的是22年合肥工业856的信号与系统试题及解析。 小马哥Tips: 本套试卷难度分析:本套试题内容难度中等,里面较多的考察了信号与系统的知识&#xff0c…

[Python]用Qt6和Pillow实现截图小工具

本文章主要讲述的内容是,使用python语言借助PyQt6和Pillow库进行简单截图工具的开发,含义一个简单的范围裁剪和软件界面。 主要解决的问题是,在高DPI显示屏下,坐标点的偏差导致QWidget显示图片不全、剪裁范围偏差问题。 适合有一点…

基于 Redis 实现分布式锁的全过程

前言 这一篇文章拖了有点久,虽然在项目中使用分布式锁的频率比较高,但整理成文章发布出来还是花了一点时间。在一些移动端、用户量大的互联网项目中,经常会使用到 Redis 分布式锁作为控制访问高并发的工具。 一、关于分布式锁 总结&#x…

QT 信号和槽教程,窗体和控件对象之间的沟通一般都使用信号和槽

Qt的信号和槽(Signals and Slots)机制是一种强大的对象间通信方式,它允许对象在完全解耦的情况下相互通信。以下是关于Qt信号和槽的简明教程: 基本概念 信号(Signal):信号是由Qt对象发出的通知…

OpenAI已全面开放自定义GPT以及文件上传等功能

今天,OpenAI兑现了前段时间做出的承诺:免费向所有用户开放GPT-4o。这意味着所有的免费用户都能使用自定义GPT模型、分析图表等其他GPT-4o新功能了。现在ChatGPT界面长这样: 可以看出,免费用户也能使用GPT store中定义好的模型&…

构建智慧监控系统的功能架构,保障安全与便利

智慧监控系统作为现代城市安全管理的重要工具,不仅能够提供有效的安防监控,还能为人们的生活带来更多的便利。本文将探讨智慧监控系统的功能架构,以实现安全和便利的双重目标。 ### 1. 智慧监控系统背景 随着城市化进程的加速,人…

构建高效便捷的家政平台系统——打造优质家政服务的关键

随着人们生活节奏的加快和工作压力的增大,家政服务的需求日益增长。为了满足这一需求,家政平台系统应运而生。本文将探讨家政平台系统的整体架构,以实现高效便捷的家政服务,打造优质家政体验。 ### 1. 家政平台系统背景 随着现代…

语音降噪算法库介绍

一.语音降噪技术方向介绍 软件上进行语音降噪目前主要是两个方向:传统降噪算法和AI降噪算法,他们各有千秋,目前看他们各有千秋,有各自适用场景。 推荐一个不错的人工智能学习网站,通俗易懂,内容全面&#…

vue3组件传值---vue组件通过属性,事件和provide,inject进行传值

通过属性传值(父传子) vue的组件具有props自建属性(自定义名称,类似于class,id的属性),通过这个属性,父组件可以向子组件传递参数,从而实现组件之间的信息传递&#xff0…

SpringSecurity6从入门到实战之Filter过滤器回顾

SpringSecurity6从入门到实战之Filter过滤器回顾 如果没有SpringSecurity这个框架,我们应该通过什么去实现客户端向服务端发送请求时,先检查用户是否登录,登录了才能访问.否则重定向到登录页面 流程图如下 官方文档:https://docs.spring.io/spring-security/referen…

自动化办公01 smtplib 邮件⾃动发送

目录 一、准备需要发送邮件的邮箱账号 二、发送邮箱的基本步骤 1. 登录邮箱 2. 准备数据 3. 发送邮件 三、特殊内容的发送 1. 发送附件 2. 发送图片 3. 发送超文本内容 4.邮件模板内容 SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议…

单点11.2.0.3备份恢复到单点11.2.0.4

保命法则:先备份再操作,磁盘空间紧张无法备份就让满足,给自己留退路。 场景说明: 1.本文档的环境为同平台、不同版本(操作系统版本可以不同,数据库小版本不同),源机器和目标机器部…

设计模式(二)工厂模式

文章目录 工厂模式简介简单工厂(Simple Factory)结构具体实现优缺点 工厂方法(Factory Method)结构具体实现优缺点 抽象工厂(Abstract Factory)结构具体实现优缺点 工厂模式简介 工厂模式是一种创建型模式…

[数据集][目标检测]焊接处缺陷检测数据集VOC+YOLO格式3400张8类别

数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):3400 标注数量(xml文件个数):3400 标注数量(txt文件个数):3400 标注…

能源SCI期刊,中科院4区,审稿快,IF=3.858

一、期刊名称 Frontiers in Energy Research 二、期刊简介概况 期刊类型:SCI 学科领域:能源 影响因子:3.858 中科院分区:4区 三、期刊征稿范围 能源研究前沿出版了整个领域的严格同行评审研究,重点是可持续和环境…

YOLOv8 深度详解!一文看懂,快速上手

YOLOv8 深度详解!一文看懂,快速上手 原文:YOLOv8 深度详解!一文看懂,快速上手 - 知乎 (zhihu.com) YOLOv8 是 ultralytics 公司在 2023 年 1月 10 号开源的 YOLOv5 的下一个重大更新版本,目前支持图像分类…

Low Memory Killer in Android

目录 低内存管理(Linux vs Android) Linux内存回收 shrink_slab原理 shrink_zone原理 oom killer oom killer设计原则 OOM killer具体实现 android的lmk(Low Memory Killer) Android系统特点 oom killer在android中的不足 ​​​​​​​LMK概…

乡村振兴与农村环境整治:加强农村环境治理,改善农村人居环境,打造干净整洁、生态宜居的美丽乡村

目录 一、引言 二、农村环境整治的重要性 1、提升农民生活质量 2、促进农村经济发展 3、保护农村生态环境 三、当前农村环境面临的问题 1、垃圾处理不当 2、污水处理设施缺乏 3、农业面源污染严重 四、加强农村环境治理的措施 1、完善农村垃圾处理体系 2、加强农村…

2010-2015 年阿拉斯加北坡苔原植物功能类型连续覆盖图

ABoVE: Tundra Plant Functional Type Continuous-Cover, North Slope, Alaska, 2010-2015 2010-2015 年阿拉斯加北坡苔原植物功能类型连续覆盖图 简介 文件修订日期:2021-08-27 数据集版本: 1 摘要 该数据集以 30 米的分辨率提供了阿拉斯加北坡约 12.5 万平方…