【垃圾回收概述及算法】
文章目录
- 1. 垃圾回收概述及算法
- 2. 垃圾回收相关算法
- 2.1 标记阶段:引用计数算法
- 2.2 标记阶段:可达性分析算法
- 2.3 对象的 finalization 机制
- 2.3.1 一个对象是否可回收的判断
- 2.4 清除阶段:标记-清除算法
- 2.5 清除阶段:复制算法
- 2.6 清除阶段:标记-压缩(整理)算法
- 2.7 小结
1. 垃圾回收概述及算法
什么是垃圾?
垃圾是指在运行程序中没有任何指针指向的对象,这个对象就是需要被回收的垃圾。
如果不及时对内存中的垃圾进行清理,那么,这些垃圾对象所占的内存空间会一直保留到应用程序的结束,被保留的空间无法被其它对象使用,甚至可能导致内存溢出
。
Java 垃圾回收机制:自动内存管理,无需开发人员手动参与内存的分配与回收,这样降低内存泄漏
和内存溢出
的风险
GC 主要关注的区域:GC 主要关注于方法区 和堆中的垃圾收集
- 频繁收集 Young 区
- 较少收集 Old 区
- 基本不收集 Perm 区(元空间)
2. 垃圾回收相关算法
对象存活判断:引用计数算法和可达性分析算法。
2.1 标记阶段:引用计数算法
对每个对象保存一个整型的引用计数器属性。用于记录对象被引用的情况。
对于一个对象 A,只要有任何一个对象引用了 A,则 A 的引用计数器就加 1;当引用失效时,引用计数器就减 1。只要对象 A 的引用计数器的值为 0,即表示对象 A 不可能再被使用,可进行回收。
优点:
- 实现简单,垃圾对象便于辨识;
- 判定效率高,回收没有延迟性。
缺点:
- 它需要单独的字段存储计数器,这样的做法增加了存储空间的开销。
- 每次赋值都需要更新计数器,伴随着加法和减法操作,这增加了时间开销。
- 引用计数器有一个严重的问题,即无法处理循环引用的情况。这是一条致命缺陷,导致在 Java 的垃圾回收器中没有使用这类算法。
2.2 标记阶段:可达性分析算法
该算法可以有效地解决在引用计数算法中循环引用的问题,防止内存泄漏的发生。
基本思路:
-
可达性分析算法是以根对象集合(GCRoots)为起始点,按照从上至下的方式搜索被根对象集合所连接的目标对象是否可达。
-
如果目标对象没有任何引用链相连,则是不可达的,就意味着该对象己经死亡,可以标记为垃圾对象。
在 Java 语言中,GC Roots 包括以下几类元素::
- 虚拟机栈(局部变量表)中引用的对象
- 本地方法栈内 JNI(通常说的本地方法)引用的对象
- 方法区中类静态属性引用的对象
- 方法区中常量引用的对象
- 比如:字符串常量池(String Table)里的引用
- 所有被同步锁 synchronized 持有的对象
- Java 虚拟机内部的引用。
- 基本数据类型对应的 Class 对象,一些常驻的异常对象(如:NullPointerException、OutOfMemoryError),系统类加载器。
- 反映 java 虚拟机内部情况的 JMXBean、JVMTI 中注册的回调、本地代码缓存等。
分代收集和局部回收(PartialGC):
只针对 Java 堆中的某一块区域进行垃圾回收(比如:典型的只针对新生代)
注意
如果要使用可达性分析算法来判断内存是否可回收,那么分析工作必须在一个能保障一致性的快照
中进行。这点不满足的话分析结果的准确性就无法保证。
这点也是导致 GC 进行时必须“stop The World”
的一个重要原因。
即使是号称(几乎)不会发生停顿的 CMS
收集器中,枚举根节点时也是必须要停顿的。
2.3 对象的 finalization 机制
finalization机制:来允许开发人员提供对象被销毁之前的自定义处理逻辑
。
当垃圾回收器发现没有引用指向一个对象,即:垃圾回收此对象之前,总会先调用这个对象的 finalize()方法。
finalize() 方法允许在子类中被重写,用于在对象被回收时进行资源释放。通常在这个方法中进行一些资源释放和清理
的工作,比如关闭文件
、套接字
和数据库连接
等。
2.3.1 一个对象是否可回收的判断
虚拟机中的对象可能的三种状态:
- 可触及的:从根节点开始,可以到达这个对象。
- 可复活的:对象的所有引用都被释放,但是对象有可能在 finalize()中复活。
- 不可触及的:对象的 finalize()被调用,并且没有复活,那么就会进入不可触及状态。不可触及的对象不可能被复活,因为finalize()只会被调用一次。
判定一个对象 objA 是否可回收,至少要经历两次标记过程:
- 如果对象 objA 到 GC Roots 没有引用链,则进行第一次标记。
- 进行筛选,判断此对象是否有必要执行 finalize()方法
- 如果对象 objA 没有重写 finalize()方法,或者 finalize()方法已经被虚拟机
调用过
,则虚拟机视为“没有必要执行”,objA 被判定为不可触及的
。 - 如果对象 objA 重写了 finalize()方法,且
还未执行过
,那么 objA 会被插入到 F-Queue 队列中,由一个虚拟机自动创建的、低优先级的 Finalizer 线程触发其 finalize()方法执行。 - finalize()方法是对象逃脱死亡的
最后机会
,稍后 GC 会对 F-Queue 队列中的对象进行第二次标记
。如果 objA 在 finalize()方法中与引用链上的任何一个对象建立了联系,那么在第二次标记时,objA 会被移出
“即将回收”集合。
2.4 清除阶段:标记-清除算法
当成功区分出内存中存活对象和死亡对象后,GC 接下来的任务就是执行垃圾回收,释放掉无用对象所占用的内存空间,以便有足够的可用内存空间为新对象分配内存。
目前在 JVM 中比较常见的三种垃圾收集算法:标记一清除算法
(Mark-Sweep)、复制算法
(copying)、标记-压缩算法
(Mark-Compact)
标记-清除算法(Mark-Sweep):
当堆中的有效内存空间(available memory)被耗尽的时候,就会停止整个程序(也被称为 stop the world
),然后进行两项工作,第一项则是标记
,第二项则是清除
- 标记<:Collector 从引用
根节点开始遍历
,标记所有被引用的对象。一般是在对象的 Header 中记录为可达对象。 - 清除:Collector 对
堆内存
从头到尾进行线性的遍历
,如果发现某个对象在其 Header 中没有标记为可达对象,则将其回收
何为清除?
这里所谓的清除并不是真的置空,而是把需要清除的对象地址保存在空闲的地址列表
里。下次有新对象需要加载时,判断垃圾的位置空间是否够,如果够,就存放覆盖
原有的地址。
缺点
- 标记清除算法的效率不算高
- 在进行 GC 的时候,需要停止整个应用程序,用户体验较差
- 这种方式清理出来的空闲内存是不连续的,产生
内存碎片
,需要维护
一个空闲列表
2.5 清除阶段:复制算法
将活着的内存空间分为两块
,每次只使用其中一块,在垃圾回收时将正在使用的内存中的存活对象复制
到未被使用的内存块中,之后清除正在使用的内存块中的所有对象,交换两个内存的角色,最后完成垃圾回收
优点
- 没有标记和清除过程,实现简单,运行
高效
- 复制过去以后保证空间的连续性,
不会出现“碎片”
问题。
缺点
- 此算法的缺点也是很明显的,就是需要
两倍的内存空间
。 - 对于
G1
这种分拆成为大量 region 的 GC,复制而不是移动,意味着 GC 需要维护 region 之间对象引用关系
,不管是内存占用或者时间开销也不小(因为堆中对象换地方了,所有引用此对象的引用地址都需要变)
应用场景
在新生代的垃圾回收,一次通常可以回收 70% - 99% 的内存空间。回收性价比很高。所以现在的商业虚拟机都是用这种收集算法回收新生代。
2.6 清除阶段:标记-压缩(整理)算法
- 第一阶段和标记清除算法一样,从根节点开始标记所有被引用对象
- 第二阶段将所有的存活对象压缩到内存的一端,按顺序排放。
- 之后,清理边界外所有的空间。
标记-压缩算法的最终效果等同于标记-清除算法执行完成后,再进行一次内存碎片整理
,因此,也可以把它称为标记-清除-压缩(Mark-Sweep-Compact)算法。
优点
- 消除了标记-清除算法当中,内存区域分散的缺点,我们需要给新对象分配内存时,JVM 只需要持有一个内存的起始地址即可。
- 消除了复制算法当中,内存减半的高额代价。
缺点:
- 从效率上来说,标记-整理算法要低于复制算法。
移动对象
的同时,如果对象被其他对象引用,则还需要调整引用的地址
- 移动过程中,需要全程暂停用户应用程序。即:
STW
2.7 小结
相关文章:

【垃圾回收概述及算法】
文章目录 1. 垃圾回收概述及算法2. 垃圾回收相关算法2.1 标记阶段:引用计数算法2.2 标记阶段:可达性分析算法2.3 对象的 finalization 机制2.3.1 一个对象是否可回收的判断 2.4 清除阶段:标记-清除算法2.5 清除阶段:复制算法2.6 清…...

2021年03月 Python(二级)真题解析#中国电子学会#全国青少年软件编程等级考试
Python编程(1~6级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 对于字典infor {“name”:“tom”, “age”:13, “sex”:“male”},删除"age":13键值对的操作正确的…...

为什么通过一致性正则化方法就可以避免将所有未标记数据集分配给同一类?
一致性正则化方法可以帮助避免将所有未标记数据分配给同一类别的原因在于它们引入了对模型输出的一致性约束,从而减轻了判别性损失(如交叉熵损失)可能导致的问题。以下是一些关键原因: 一致性反馈: 一致性正则化方法…...

第4章 决策树
文章目录 4.1 基本流程4.2 划分选择4.2.1 信息增益4.2.2 增益率4.2.3 基尼指数 4.3 剪枝处理4.3.1 预剪枝4.3.2 后剪枝 4.4 连续与缺失值4.4.1 连续值处理4.4.2 缺失值处理 4.5 多变量决策树4.6 阅读材料 4.1 基本流程 决策树也称判定树,是一类常见的机器学习方法。…...

在Remix中编写你的第一份智能合约
智能合约简单来讲就是:部署在去中心化区块链上的一个合约或者一组指令,当这个合约或者这组指令被部署以后,它就不能被改变了,并会自动执行,每个人都可以看到合约里面的条款。更深层次的理解就是:这些代码会…...

如何查看dll文件内导出函数名称
一 使用VS自带工具 进入VS开发环境,然后Tools -> Visual studio 2017 Command Prompt,打开兼容工具命令提示符, 如果工具 目录下没有命令行提示,可以从开始菜单找到VS的命令行提示符。 cd到dll所在目录,输入命令…...

学习笔记|串口通信的基础知识|同步/异步|RS232|常见的串口软件的参数|STC32G单片机视频开发教程(冲哥)|第二十集:串口通信基础
目录 1.串口通信的基础知识串口通信(Serial Communication)同步/异步?全双工?常见的串口软件的参数 2.STC32的串口通信实现原理引脚选择:实现分时复用模式选择串口1模式1,模式1波特率计算公式 3.串口通信代码实现编写串口1通信程序…...

JAVA String 和 String[][]互转的两种方法
第一种方法: <dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.40</version> </dependency>字符串转数组: String s "[[22,23,23],[1,10,20]]"…...

推荐几个制作svg的工具
以下是一些用于制作SVG(可缩放矢量图形)的工具和软件,适用于不同技能级别和需求: Adobe Illustrator:作为业界标准之一,Adobe Illustrator是功能强大的矢量图形编辑软件,适用于专业设计师和创意…...

Java实现防重复提交,使用自定义注解的方式
目录 1.背景 2.思路 3.实现 创建自定义注解 编写拦截器 4.使用 5.验证...

Springboot实现Web组件注册
一、前言 在实际开发中,有时候我们可能使用springboot注册web组件,实现某些功能,比如我们需要生成一些api来提供对外的服务,而对应的路径其实是不固定的,那么这种情况下,其实是可以通过这种方式来注册web组…...

Element组件案例 Vue路由 前端打包部署步骤
目录 Element组件案例案例需求与分析环境搭建整体布局顶部标题左侧导航栏核心-右侧导航栏表格编写表单编写分页工具栏编写 异步数据加载异步加载数据性别展示修复图片展示修复 Vue路由Vue路由简介Vue路由入门 打包部署前端工程打包部署前端工程nginx介绍部署 Element组件案例 …...

mysql5.7停止维护时间
mysql5.7将于2023年10月停止官网支持和更新;老项目要准备升级,新项目的mysql必须是mysql8.0(2023-10) 官方升级咨询地址 oracle官方升级咨询地址https://go.oracle.com/LP116153?elq_mid247718&sh1518132002061316121320310…...

解密.kat6.l6st6r勒索病毒:保护数据的关键方法
导言: 网络威胁如雨后春笋,而 .kat6.l6st6r 勒索病毒则是其中一个异常狡猾的恶棍。本文91数据恢复将深入探讨 .kat6.l6st6r 勒索病毒的特点、数据恢复方法以及如何有效地预防这一数字威胁。 数据的重要性不容小觑,您可添加我们的技术服务号&a…...

Godot 添加信号
前言 Godot 里面C#和GDScirpt 的用法完全不一样,网上相关资料太少了。 什么是信号 信号分为信号源,触发,目的节点。信号源在某些条件下触发信号,比如按钮点击,鼠标悬停等事件 #mermaid-svg-wyr9ARVcBFmUUu8y {font-…...

JS如何判断文字是否溢出(被ellipsis)?
如果想要文本超出宽度后用省略号省略,只需要加上以下的css就行了。 .ellipsis {overflow: hidden;text-overflow: ellipsis;white-space: nowrap; }3行css搞定,但是问题来了:如果我们想要当文本被省略的时候,也就是当文本超出指定…...

pb:常用函数和语句清单
pb:常用函数和语句清单 PB中提供了600多个函数,这还没有将B/S开发、数据窗口对象中的函数计算在内。但是,只要掌握、熟练运用、真正理解下面的这些函数(包括部分语句)就可以开发软件项目了。这些函数和语句是我给学员讲课时开发的一个完整的管理系统(提供了MIS必须的完整模…...

(8)SpringMVC中的视图类型及其特点,以及视图控制器view-controller的配置
SpringMVC的视图 转发和重定向的区别及其原理,参考文章 视图类型及特点 视图的作用就是将Model中的数据渲染到页面上并展示给用户,SpringMVC中视图对应的View接口有三种实现类对应三种视图解析器 默认有转发视图InternalResourceView和重定向视图RedirectView以及Thymeleaf…...

ansible学习笔记分享
yum install ansible -y #安装,注意yum源问题 yum源: yum install epel-release -y mv /etc/yum.repos.d/epel.repo /etc/yum.repos.d/epel.repo.bak >> /dev/null yum clean all rpm -Uvh http://mirrors.ustc.edu.cn/epel/epel-releas…...

以dzzoffice为例设置通过 SOCKET 连接 SMTP 服务器发送(支持 ESMTP 验证)
在测试dzzoffice的过程中,需要配置邮件服务器,dzzoffice的邮件设置有三种选项: 1、通过 PHP 函数的 sendmail 发送(推荐此方式) 2、通过 SOCKET 连接 SMTP 服务器发送(支持 ESMTP 验证) 3、通过 PHP 函数 SMTP 发送 Email(仅 Windows 主机下有…...

加拿大艾伯塔省执法部门利用OpenText Encase显着提高案件效率
艾伯塔省执法部门利用OpenText Encase显着提高案件效率 Internet Child Exploitation Unit (ICE) 使用OpenText EnCase Forensic 加快结案进度并起诉更多罪犯 挑战 从证据收集到报告和起诉的过程非常耗时; 需要工具帮助快速可靠地收集、分析和存储数字证据。 结果 显著提高案…...

【Codeforces】Educational Codeforces Round 156 [Rated for Div. 2]
hh第一次记录cf。 复盘 ab题目比较清晰,只开了这两题,后面看了下cd,即使开了翻译也看不懂题目是什么意思,最后放弃睡觉了。。 a是一道思维题,翻了下别人写的发现大家写的各不相同hh b是一道数学题,过程有点…...

结合swagger的前端架构小记
1.引言 开发中,我们是否经常遇到以下痛点: 项目越大,启动和热更新越来越慢,启动都要花个3-5分钟以上没有类型,接口返回的Object不拿到真实数据都不知道有哪些字段需要手动写很多request函数去调用api,手动…...

Python字典全解析:从基础到高级应用
更多资料获取 📚 个人网站:涛哥聊Python 字典是一种强大而多才多艺的数据类型,它以键-值对的形式储存信息,让我们能够以惊人的效率处理和管理数据。 字典能够将键和值关联在一起,使得数据的存储和检索变得非常高效。…...

Fourier变换中的能量积分及其详细证明过程
Fourier变换中的能量积分及其详细证明过程 在使用Fourier变换分析信号时候,有时需要用到能量积分。本文对Fourier变换的能量积分进行分析。 一、Fourier变换中的能量积分 若 F ( ω ) F [ f ( t ) ] F(\omega)\mathscr F[f(t)] F(ω)F[f(t)],则有 ∫…...

保护 Web 服务器安全性
面向公众的系统(如 Web 服务器)经常成为攻击者的目标,如果这些业务关键资源没有得到适当的保护,可能会导致安全攻击,从而导致巨大的财务后果,并在客户中失去良好的声誉。 什么是网络服务器审核 当有人想要…...

docker数据管理和网络通信
docker数据管理 管理 Docker 容器中数据主要有两种方式: 数据卷(Data Volumes)和数据卷容器(DataVolumes Containers)。 1.数据卷 数据卷是一个供容器使用的特殊目录,位于容器中。可将宿主机…...

代理IP与Socks5代理:网络工程师的神奇魔法棒
网络工程师是数字世界的魔法师,而代理IP和Socks5代理则是他们的神奇魔法棒。这两项技术在跨界电商、爬虫、出海业务、网络安全和游戏等领域中,为网络工程师提供了强大的工具,让他们能够创造技术的奇迹。本文将深入研究这些神奇魔法棒在不同领…...

【K8S系列】深入解析k8s 网络插件—kube-router
序言 做一件事并不难,难的是在于坚持。坚持一下也不难,难的是坚持到底。 文章标记颜色说明: 黄色:重要标题红色:用来标记结论绿色:用来标记论点蓝色:用来标记论点 在现代容器化应用程序的世界中…...

Flutter的Platform介绍-跨平台开发,如何根据不同平台创建不同UI和行为
文章目录 Flutter跨平台概念介绍跨平台开发平台相关性Platform ChannelPlatform-specific UIPlatform Widgets 如何判断当前是什么平台实例 Platform 类介绍获取当前平台的名称检查当前平台其他属性 利用flutter设计跨Android和IOS平台应用的技巧1. 遵循平台的设计准则2. 使用平…...