GC--垃圾回收

目录

垃圾回收概念

什么是垃圾?

垃圾回收机制什么时候会进行GC??

应该关心垃圾回收那些哪些区域的回收

垃圾回收相关算法

垃圾回收算法:[标记阶段、回收阶段]

垃圾标记阶段

标记阶段的目的

引用计数算法(目前没有在使用)

什么是循环依赖问题??

可达性分析算法(当前使用的算法)

什么是根对象??

垃圾回收阶段

标记-复制算法(Copying)

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

标记-压缩算法(Mark-Compact)

对象的 finalization 机制

finalize()方法 

对象在虚拟机中的三种状态

垃圾回收相关概念

内存溢出与内存泄漏

STW (stop the world)

垃圾回收器

垃圾回收算法是理论,垃圾回收器是回收的实践者

垃圾收集器分类

按线程数分类

        单线程垃圾回收器(Serial)

        多线程垃圾回收器(Parallel)

按工作模式分

        独占式垃圾回收器(STW)

        并发式垃圾回收器

按工作的内存区间分

        年轻代的垃圾回收器

        老年代的垃圾回收器

GC性能指标

CMS回收器(并发标记清除)[追求低停顿]

垃圾回收过程

        初始标记:

        并发标记:

        重新标记:

        并发清除:

G1垃圾回收器     

垃圾回收过程 

 初始标记:

 并发标记:

 最终标记:

 筛选回收:


垃圾回收概念

什么是垃圾?

        垃圾是指在运行程序中没有任何引用指向的对象,这个对象就是垃圾,垃圾对象需要被清理回收,否则会一直被占用,浪费空间,其他新对象无法使用该控件,严重的话会造成内存溢出

垃圾回收机制什么时候会进行GC??

  1. 堆内存不足:当JVM的堆内存不足以分配新的对象时,会触发垃圾回收以释放不再使用的内存空间。
  2. 系统调用:可以通过调用System.gc()Runtime.getRuntime().gc()来建议JVM进行垃圾回收,但具体何时执行是由JVM决定的。
  3. 作用域结束:当对象的作用域结束时,例如方法执行完毕,该作用域内的局部变量将不再被引用,这些对象就可能被回收。
  4. 程序正常退出:当程序执行了System.exit()方法时,JVM在退出前会进行垃圾回收以清理资源。
  5. 对象引用丢失:如果一个对象没有任何引用指向它,那么这个对象就成为垃圾回收的候选对象。
  6. 内存泄漏检测:某些JVM实现可能会定期检查内存使用情况,以识别和处理内存泄漏问题。
  7. 定时回收:一些JVM实现可能会有一个定时机制,定期执行垃圾回收以保持内存的整洁。
  8. 老年代空间不足:当老年代空间不足以容纳新晋升的对象或不足以进行Minor GC时,会触发Full GC。
  9. 元数据区溢出:在Java 8及以后的版本中,如果元空间(Metaspace)不足以存储类的元数据,也可能触发垃圾回收。
  10. 新生代空间不足:当新生代空间不足以分配新对象时,会触发Minor GC。
  11. Survivor空间溢出:如果Survivor空间中的对象太多,无法容纳新的对象,也会触发Minor GC。

应该关心垃圾回收那些哪些区域的回收

重点回收堆{

        频繁回收新生代

        较少回收老年代

}

较少回收方法区

垃圾回收相关算法

垃圾回收算法:[标记阶段、回收阶段]

垃圾标记阶段

标记阶段的目的

标记阶段的目的主要是为了判断对象是否为垃圾对象

        在 GC 执行垃圾回收之前,首先需要区分出内存中哪些是有用对象,哪些是垃圾对象。只有被标记为己经是垃圾对象,GC 才会在执行垃圾回收时,释放掉其所占用的内存空间,因此这个过程我们可以称为垃圾标记阶段。 

        那么怎样判定一个对象是否为垃圾对象呢?简单来说:当一个对象没有任何引用指向时,就可以称之为垃圾对象。

引用计数算法(目前没有在使用)

        为每个对象保存一个整型的引用计数器属性,用于记录对象被引用的情况

 对于一个对象A,只要有一个引用指向了对象A,则对象A的引用计数器属性加1;当引用失效时,引用计数器就减1;只要对象A不可能再被使用,则表示可进行回收。

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

缺点:

        这样的做法增加了存储空间的开销(占内存)

        每次操作都需要更新计数器,增加了时间开销(费时间)

        不可处理循环依赖问题

什么是循环依赖问题??

 

        当外界有引用指向这个系统时,A的引用会指向B,B的引用指向C,C引用又指向A,这样如果外部请求引用切断时,该系统与外界就失去了联系,但是他们的程序计数器属性不为0,这样会导致循环引用问题,从而导致内存泄漏 

可达性分析算法(当前使用的算法)

可达性分析:也可称之为根搜索算法、追踪性垃圾收集

        相较于引用计数算法,可达性分析算法有效的解决了引用计数算法中的循环引用问题,防止内存泄露问题的发生。

        从一些活跃对象(GC Roots)开始搜索,与跟对象相关联的对象都是被使用的对象,与根对象或者根对象的引用链不相连的,则称之为垃圾对象。

什么是根对象??
  1. 虚拟机栈中引用的对象(正在运行的方法中的对象)
  2. 静态属性(static)
  3. 被用来当做同步锁的
  4. Java系统中的类

垃圾回收阶段

标记-复制算法(Copying)

        可以有多块内存,每次至少有一块是空闲的,复制算法会将存活的对象移动到未被使用的空间中,清除其它块中所有的垃圾对象。

特点:内存碎片少,适用于存活对象少,垃圾对象多的区域(适用于新生代)

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

        存活对象的位置不变,垃圾对象的地址记录在一个空闲的列表中,如果创建新对象,则将空闲列表中垃圾对象覆盖掉。

特点:不移动对象,回收后会产生内存碎片(适用于老年代)

标记-压缩算法(Mark-Compact)

        标记-清除算法+重新排列

        将存活的对象重新排列,其余空间进行清理,又称:[标记-清除-压缩算法]

 

特点:回收后压缩,不会产生内存碎片(适用于老年代)but效率低

对象的 finalization 机制

        Java 语言提供了对象终止(finalization)机制来允许开发人员提供对象被销毁 之前的自定义处理逻辑(如Servlet生命周期中的destroy()方法)

finalize()方法 

        Object类中,在对象回收之前,可以在此方法中执行一些所需要的逻辑(close()操作等),在对象被判定为垃圾对象时,回收之前会调用finalize()方法,finalize()方法只会被调用一次。

对象在虚拟机中的三种状态

  • 可触及的:从根节点可到达的。
  • 可复活的:被标记为垃圾对象,但还未finalize()的。
  • 不可触及的:finalize()已调用,且被垃圾回收机制执行的。

垃圾回收相关概念

内存溢出与内存泄漏

内存溢出:

        内存溢出Out Of Memory,简称OOM

        经过垃圾回收后,内存仍然不够,导致程序崩溃。

        大多数情况下GC会根据各个年龄段的不同来进行垃圾回收,但是 如果实在回收不了,就会进行 Full GC ,这时候会释放出大量的空间,以供程序应用继续使用。

        存溢出可能导致程序崩溃或系统的不稳定。

内存泄漏:(内存浪费)

        一个对象在程序中不会被使用,但是垃圾回收器不能回收,会一直占用内存,进而导致内存泄漏(e.g:IO,数据库连接等为close()、单例模式中单例对象,整个程序中使用唯一的对象,如果不关闭,回收器就无法进行回收)

STW (stop the world)

        Stop-the-World,简称 STW,当垃圾回收时(标记/回收)会导致其他用户线程暂停,必须保证分析时,其他对象的引用不会出现变化,避免出现漏标、错标等问题,保证分析的准确性。

垃圾回收器

垃圾回收算法是理论,垃圾回收器是回收的实践者

垃圾收集器分类

按线程数分类

        单线程垃圾回收器(Serial)

                适用于一些小的设备,只有一个线程进行垃圾回收

        多线程垃圾回收器(Parallel)

                提供多个线程进行垃圾回收

按工作模式分

        独占式垃圾回收器(STW)

                垃圾回收线程执行时,其他用户线程暂停

        并发式垃圾回收器

                垃圾回收线程可以和用户线程同时执行

按工作的内存区间分

        年轻代的垃圾回收器
        老年代的垃圾回收器

GC性能指标

        吞吐量:运行用户代码的时间占总运行时间的比例(总运行时间:程序的运行时间+内存回收的时间)

        垃圾收集开销:垃圾收集所用时间与总运行时间的比例。

        暂停时间:执行垃圾收集时,程序的工作线程被暂停的时间。

        内存占用:Java 堆区所占的内存大小。

CMS回收器(并发标记清除)[追求低停顿]

        首个实现垃圾收集线程与用户线程可以同时执行的。

        注意:不是所有都并发执行,也会有独占执行。

垃圾回收过程

        初始标记:

                Stop The World,仅使用一条初始标记线程对所有与 GC Roots 直接关联的对象进行标记。

        并发标记:

                垃圾回收线程,与用户线程并发执行。此过程进行可达性分析,标记出所有废弃对象。

        重新标记:

                Stop The World,使用多条标记线程并发执行,将刚才并发标记过程中新出现的废弃对象标记出来。

        并发清除:

                只使用一条 GC 线程,与用户线程并发执行,清除刚才标记的对象。 这个过程非常耗时。

        并发标记与并发清除过程耗时最长,且可以与用户线程一起工作,因此,总体上说,CMS 收集器的内存回收过程是与用户线程一起并发执行的。

G1垃圾回收器     

        适合大型服务器,内存大,CPU更先进,将每个区域(Eden,幸存者,老年代)又划分成若干小的区域,哪个区域垃圾数量多,优先回收哪个区域。可以做到整堆管理收集回收,也可以并发收集回收。

垃圾回收过程 

 初始标记:

                标记出 GC Roots 直接关联的对象,这个阶段速度较快,需要停止用户线程,单线程执行。

 并发标记:

                从 GC Root 开始对堆中的对象进行可达性分析,找出存活对象,这个阶段耗时较长,但可以和用户线程并发执行。

 最终标记:

                修正在并发标记阶段引用户程序执行而产生变动的标记记录。

 筛选回收:

                筛选回收阶段会对各个区域的回收价值和成本进行排序,根据用户所期望的 GC 停顿时间来指定回收计划(用最少的时间来回收包含垃圾最多的区域)。

这就是 Garbage First 的由来——第一时间清理垃圾最多的区块,这里为了提高回收效率,并没有采用和用户线程并发执行的方式,而是停顿用户线程。

适用场景:要求尽可能可控 GC 停顿时间;内存占用较大的应用。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

实现类似 Word 协同编辑--Canvas-Editor

前言 对于word的协同编辑,已经构思很久了,但是没有找到合适的插件。今天推荐基于canvas/svg 的富文本编辑器 canvas-editor,能实现类似word的基础功能,如果后续有更好的,也会及时更新。 Canvas-Editor效果图: 官方文…

FFmpeg--AAC音频解码流程

文章目录 AAC 组成函数分析读aac帧写aac帧aac的head参数设置 运行结果 AAC 组成 AAC音频格式:是⼀种由MPEG-4标准定义的有损⾳频压缩格式 ADTS:是AAC音频的传输流格式 AAC音频文件的每一帧由ADTS Header和AAC Audio Data组成 每⼀帧的ADTS的头⽂件都包含了⾳频的采…

llama-index调用qwen大模型实现RAG

背景 llama-index在实现RAG方案的时候多是用的llama等英文大模型,对于国内的诸多模型案例较少,本次将使用qwen大模型实现llama-index的RAG方案。 环境配置 (1)pip包 llamaindex需要预装很多包,这里先把我成功的案例…

计算机网络——概述

计算机网络——概述 计算机网络的定义互连网(internet)互联网(Internet)互联网基础结构发展的三个阶段第一个阶段——APPANET第二阶段——商业化和三级架构第三阶段——全球范围多层次的ISP结构 ISP的作用终端互联网的组成边缘部分…

Python 映射函数map()详解

一、映射函数定义 它用于对容器中的元素进行映射(或变换) 二、映射函数语法 map(function, iterable) function:一个提供变换规则的函数,返回变换之后的元素iterable:一个或多个序列(可迭代对象&#xff09…

新零售SaaS架构:订单履约系统架构设计(万字图文总结)

什么是订单履约系统? 订单履约系统用来管理从接收客户订单到将商品送达客户手中的全过程。 它连接了上游交易(客户在销售平台下单环)和下游仓储配送(如库存管理、物流配送),确保信息流顺畅、操作协同&…

【ElasticSearch】es索引、映射、文档基本操作复杂查询

各位小伙伴们大家好,欢迎来到这个小扎扎的ElasticSearch专栏,本篇博客由B战尚硅谷的ElasticSearch视频总结而来,鉴于 看到就是学到、学到就是赚到 精神,这波依然是血赚 ┗|`O′|┛ 🌆 内容速览 1 es数据格…

【node版本问题】运行项目报错 PostCSS received undefined instead of CSS string

最近该项目没有做任何修改,今天运行突然跑不起来报错了 PostCSS received undefined instead of CSS string 【原因】突然想起来期间有换过 node 版本为 16.17.1 【解决】将 node 版本换回之前的 14.18.0 就可以了

vue3中基于路由层面和组件层面进行用户角色及权限控制的方法解析

文章目录 一、权限控制二、路由层面控制三、组件层面控制1、使用自定义指令2、使用方法控制3、封装一个权限控制组件来实现组件层面控制权限3.1、组件页面 Authority.vue3.2、使用页面 app.vue3.3、效果预览 一、权限控制 随着前端技术的不断发展,越来越多的前端框…

Linux命令记不住?保姆级教程来了

在软件开发过程中,Linux操作系统因其稳定性、安全性和高效性而备受青睐。作为开发者,熟练掌握Linux常用命令,不仅可以提高工作效率,还能更好地管理服务器和进行代码部署。本文将介绍一些开发常用的Linux命令及其应用场景&#xff…

JavaScript数组常见实例方法:forEach、filter、map、reduce、find、every等

博客背后的故事 其实我23年7月就学过这些数组方法了,但是为什么24年3月才做笔记呢?这就要讲一个小故事了(不想听故事的同学自行拖动滚动条) 24年年初我和两个队友合作开发一个小程序。JavaScript中数组的实例方法我已经学了很久…

Docker下Jenkins打包java项目并部署

docker 构建Jenkins sudo docker run --namezen_haslett --userjenkins --privilegedtrue --volume/home/cyf/server/jenkins/jenkins_home:/var/jenkins_home -v /usr/lib/jvm/java-17-openjdk-amd64:/usr/lib/jvm/java-17-openjdk-amd64 -v /usr/lib/maven/apache-mav…

VIM编译器的安装

文章目录 前言一、VIM软件安装二、遇到问题三、VIM使用1.文档创建命令touch2.VIM编译器输入模式3.VIM编译器指令模式3.VIM编译器底行模式4.VIM编译器使用小技巧 前言 💦 我们如果要在终端模式下进行文本编辑或者修改文件就可以使用 VIM 编辑器,VIM 编辑…

treeview控件的应用

1.分类 treeview控件的基本应用,可以用于商品分类、文件分类等等。 2.辅助决策 treeview可以组成决策树,用来帮助人们做选择。比如说今天中午吃什么菜? 如果我来选择的话,那就是:不吃辣-鲁菜-糖醋鲤鱼。 3.求解算…

AD1102 小封装的3.7V锂电池转干电池使用的充放电管理芯片 替代传统干电池、镍氢电池

AD1102是一款锂电池充放电管理专用芯片。充电工作时,可以为 3.7V锂电池进行充电,电流最高可配置 1A。放电工作时,采用开关频率1MHz同步降压转换器进行放电,放电电流可以达到 3A。内部集成欠压保护、短路保护、过温保 护功能。 …

二 centos 7.9 磁盘挂载

上一步 一 windso10 笔记本刷linux cent os7.9系统-CSDN博客 笔记本有两个盘,系统装在128G的系统盘上,现在把另外一个盘挂载出来使用 lsblk 发现磁盘已经分好了,直接挂载就好了,参考文章:Centos7.9 挂载硬盘_centos7.9挂载硬盘-CSDN博客 永久挂载 lsblk -f分区格式化 mkfs…

XUbuntu22.04之reboot关机无效, 定制重启和关机(二百二十)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒…

2024届 C++ 刷题 笔试强训 Day 01

选择题 01 以下for循环的执行次数是&#xff08;&#xff09; for(int x 0, y 0; (y 123) && (x < 4); x); A 是无限循环 B 循环次数不定 C 4次 D 3次 解题思路&#xff1a; 我们直接来看本道题中最关键的部分&#xff1a;(y 123) && (x < 4)。 (y…

漏洞挖掘 | 公益SRC上榜技巧

目录 1、寻找漏洞 2、挖掘漏洞 3、提交报告 4、上榜吉时 5、快速上分 6、小技巧&#xff1a;冲榜拿分制胜点-拉开人与人之间的差距 1、寻找漏洞 寻找漏洞的2种办法&#xff1a; 1)谷歌语法 注意&#xff1a;用谷歌语法找站的时候&#xff0c;要加点中文&#xff0c;不然搜…

STL之set容器代码详解

1 基础概念 所有元素都会在插入时自动被排序 本质&#xff1a; set/multiset属于关联式容器&#xff0c;底层结构是用二叉树实现。 set和multiset区别&#xff1a; set不允许容器中有重复的元素&#xff1b; multiset允许容器中有重复的元素 。 2 代码示例 Talk is chea…