java八股文面试[JVM]——垃圾回收

参考:JVM学习笔记(一)_卷心菜不卷Iris的博客-CSDN博客

GC垃圾回收
面试题:

JVM内存模型以及分区,需要详细到每个区放什么
堆里面的分区:Eden,survival from to,老年代,各自的特点。


GC的三种收集方法:标记清除、标记整理、复制算法的原理与特点,分别用在什么地方

针对RockitMQ 消息中间件的服务器,应该使用什么样的GC算法?(TODO


Minor GC与Full GC分别在什么时候发生

GC发生的区域:方法区 和 堆

在这里插入图片描述

 
JVM垃圾判定算法:(对象已死?)

引用计数法(Reference-Counting)
可达性分析算法(根搜索算法)

垃圾判定
4.2.1. 引用计数法(Reference-Counting)
引用计数算法是通过判断对象的引用数量来决定对象是否可以被回收。

给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻计数器为0的对象就是不可能再被使用的。

优点:

简单,高效,现在的objective-cpython等用的就是这种算法。
缺点:

引用和去引用伴随着加减算法,影响性能

很难处理循环引用,相互引用的两个对象则无法释放。

因此目前主流的Java虚拟机都摒弃掉了这种算法。
 

可达性分析算法

这个算法的基本思想就是通过一系列的称为 “GC Roots” 的对象作为起点,从这些节点开始向下搜索,节点所走过的路径称为引用链,当一个对象到 GC Roots 没有任何引用链相连的话,则证明此对象是不可用的。

在Java语言中,可以作为GC Roots的对象包括下面几种:

虚拟机栈(栈帧中的本地变量表)中的引用对象。
方法区中的类静态属性引用的对象。
方法区中的常量引用的对象。
本地方法栈中JNI(Native方法)的引用对象
真正标记以为对象为可回收状态至少要标记两次。

第一次标记:不在 GC Roots 链中,标记为可回收对象。

第二次标记:判断当前对象是否实现了finalize() 方法,如果没有实现则直接判定这个对象可以回收,如果实现了就会先放入一个队列中。并由虚拟机建立一个低优先级的程序去执行它,随后就会进行第二次小规模标记,在这次被标记的对象就会真正被回收了!
在这里插入图片描述

四种引用
平时只会用到强引用软引用

强引用:

​ 类似于 Object obj = new Object(); 只要强引用还存在,垃圾收集器永远不会回收掉被引用的对象。

软引用:

SoftReference 类实现软引用。在系统要发生内存溢出异常之前,才会将这些对象列进回收范围之中进行二次回收。如果这次回收还没有足够的内存,才会抛出内存溢出异常。软引用可用来实现内存敏感的高速缓存。

弱引用:

​ WeakReference 类实现弱引用。对象只能生存到下一次垃圾收集之前。在垃圾收集器工作时,无论内存是否足够都会回收掉只被弱引用关联的对象。

虚引用:

​ PhantomReference 类实现虚引用。无法通过虚引用获取一个对象的实例,为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。

作用:

虚引用主要用来跟踪对象被垃圾回收器回收的活动。虚引用软引用和弱引用的一个区别在于:虚引用必须和引用队列 (ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之 关联的引用队列中。你声明虚引用的时候是要传入一个queue的。当你的虚引用所引用的对象已经执行完finalize函数的时候,就会把对象加到queue里面。你可以通过判断queue里面是不是有对象来判断你的对象是不是要被回收了

 
GC垃圾回收主要有四大算法:(怎么找到已死对象并清除?)

复制算法(Copying)
标记清除(Mark-Sweep)
标记压缩(Mark-Compact),又称标记整理
分代收集算法(Generational-Collection)

GC的特点

  • 次数上频繁收集Young区
  • 次数上较少收集Old区
  • 基本不动Perm区
垃圾回收算法
在介绍JVM垃圾回收算法前,先介绍一个概念:Stop-the-World

Stop-the-world意味着 JVM由于要执行GC而停止了应用程序的执行,并且这种情形会在任何一种GC算法中发生。当Stop-the-world发生时,除了GC所需的线程以外,所有线程都处于等待状态直到GC任务完成。事实上,GC优化很多时候就是指减少Stop-the-world发生的时间,从而使系统具有高吞吐 、低停顿的特点。

1. 复制算法(Copying)
该算法将内存平均分成两部分,然后每次只使用其中的一部分,当这部分内存满的时候,将内存中所有存活的对象复制到另一个内存中,然后将之前的内存清空,只使用这部分内存,循环下去。
在这里插入图片描述

优点:

实现简单
不产生内存碎片
缺点:

将内存缩小为原来的一半,浪费了一半的内存空间,代价太高;如果不想浪费一半的空间,就需要有额外的空间进行分配担保,以应对被使用的内存中所有对象都100%存活的极端情况,所以在老年代一般不能直接选用这种算法。

如果对象的存活率很高,我们可以极端一点,假设是100%存活,那么我们需要将所有对象都复制一遍,并将所有引用地址重置一遍。复制这一工作所花费的时间,在对象存活率达到一定程度时,将会变的不可忽视。 所以从以上描述不难看出,复制算法要想使用,最起码对象的存活率要非常低才行,而且最重要的是,我们必须要克服50%内存的浪费。

年轻代中使用的是Minor GC,这种GC算法采用的是复制算法(Copying)。

​ HotSpot JVM把年轻代分为了三部分:1个Eden区和2个Survivor区(分别叫from和to)。默认比例为8:1:1,一般情况下,新创建的对象都会被分配到Eden区。因为年轻代中的对象基本都是朝生夕死的(90%以上),所以在年轻代的垃圾回收算法使用的是复制算法。

​ 在GC开始的时候,对象只会存在于Eden区和名为“From”的Survivor区,Survivor区“To”是空的。紧接着进行GC,Eden区中所有存活的对象都会被复制到“To”,而在“From”区中,仍存活的对象会根据他们的年龄值来决定去向。对象在Survivor区中每熬过一次Minor GC,年龄就会增加1岁。年龄达到一定值(年龄阈值,可以通过-XX:MaxTenuringThreshold来设置)的对象会被移动到年老代中,没有达到阈值的对象会被复制到“To”区域。经过这次GC后,Eden区和From区已经被清空。这个时候,“From”和“To”会交换他们的角色,也就是新的“To”就是上次GC前的“From”,新的“From”就是上次GC前的“To”。不管怎样,都会保证名为To的Survivor区域是空的。Minor GC会一直重复这样的过程,直到“To”区被填满,“To”区被填满之后,会将所有对象移动到年老代中。

在这里插入图片描述

 

因为Eden区对象一般存活率较低,一般的,使用两块10%的内存作为空闲和活动区间,而另外80%的内存,则是用来给新建对象分配内存的。一旦发生GC,将10%的from活动区间与另外80%中存活的eden对象转移到10%的to空闲区间,接下来,将之前90%的内存全部释放,以此类推。

2.标记清除(Mark-Sweep)
“标记-清除”(Mark Sweep)算法是几种GC算法中最基础的算法,是因为后续的收集算法都是基于这种思路并对其不足进行改进而得到的。正如名字一样,算法分为2个阶段:

标记出需要回收的对象,使用的标记算法均为可达性分析算法。

回收被标记的对象。

在这里插入图片描述

缺点:

  • 效率问题(两次遍历)

  • 空间问题(标记清除后会产生大量不连续的碎片。JVM就不得不维持一个内存的空闲列表,这又是一种开销。而且在分配数组对象的时候,寻找连续的内存空间会不太好找。)

3. 标记压缩(Mark-Compact)

标记-整理法是标记-清除法的一个改进版。同样,在标记阶段,该算法也将所有对象标记为存活和死亡两种状态;不同的是,在第二个阶段,该算法并没有直接对死亡的对象进行清理,而是通过所有存活对像都向一端移动,然后直接清除边界以外的内存。

在这里插入图片描述

优点:

​ 标记/整理算法不仅可以弥补标记/清除算法当中,内存区域分散的缺点,也消除了复制算法当中,内存减半的高额代价。

缺点:

​ 如果存活的对象过多,整理阶段将会执行较多复制操作,导致算法效率降低。

老年代一般是由标记清除或者是标记清除与标记整理的混合实现。

 在这里插入图片描述

4. 分代收集算法(Generational-Collection)

内存效率:复制算法>标记清除算法>标记整理算法(此处的效率只是简单的对比时间复杂度,实际情况不一定如此)。
内存整齐度:复制算法=标记整理算法>标记清除算法。
内存利用率:标记整理算法=标记清除算法>复制算法。

可以看出,效率上来说,复制算法是当之无愧的老大,但是却浪费了太多内存,而为了尽量兼顾上面所提到的三个指标,标记/整理算法相对来说更平滑一些,但效率上依然不尽如人意,它比复制算法多了一个标记的阶段,又比标记/清除多了一个整理内存的过程

难道就没有一种最优算法吗?

回答:无,没有最好的算法,只有最合适的算法。==========>分代收集算法。

分代回收算法实际上是把复制算法和标记整理法的结合,并不是真正一个新的算法,一般分为:老年代(Old Generation)和新生代(Young Generation),老年代就是很少垃圾需要进行回收的,新生代就是有很多的内存空间需要回收,所以不同代就采用不同的回收算法,以此来达到高效的回收算法。

年轻代(Young Gen)

​ 年轻代特点是区域相对老年代较小,对像存活率低。

​ 这种情况复制算法的回收整理,速度是最快的。复制算法的效率只和当前存活对像大小有关,因而很适用于年轻代的回收。而复制算法内存利用率不高的问题,通过hotspot中的两个survivor的设计得到缓解。

老年代(Tenure Gen)

​ 老年代的特点是区域较大,对像存活率高。

​ 这种情况,存在大量存活率高的对像,复制算法明显变得不合适。一般是由标记清除或者是标记清除与标记整理的混合实现。
 

 

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

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

相关文章

【halcon深度学习】图像分割数据集格式的转换

前言 目前用于**图像分割的**数据集,我目前接触到的用的比较多的有: 1 PASCAL VOC 2 COCO 3 YOLO 4 Halcon自己的格式(其实就是Halcon字典类型)当前我涉及到计算机视觉中的数据集格式有,PASCAL VOC、COCO 和 YOLO 用于…

英特尔开始加码封装领域 | 百能云芯

在积极推进先进制程研发的同时,英特尔正在加大先进封装领域的投入。在这个背景下,该公司正在马来西亚槟城兴建一座全新的封装厂,以加强其在2.5D/3D封装布局领域的实力。据了解,英特尔计划到2025年前,将其最先进的3D Fo…

计算机毕设 基于机器视觉的二维码识别检测 - opencv 二维码 识别检测 机器视觉

文章目录 0 简介1 二维码检测2 算法实现流程3 特征提取4 特征分类5 后处理6 代码实现5 最后 0 简介 今天学长向大家介绍一个机器视觉的毕设项目,二维码 / 条形码检测与识别 基于机器学习的二维码识别检测 - opencv 二维码 识别检测 机器视觉 1 二维码检测 物体检…

SAP-FI-会计凭字段替代OBBH

会计凭证替代OBBH 业务:文本必须等于某个字段的值,例如凭证日期 关闭确认功能,输入OBBH 双击“替代”进入功能配置,或者用GGB1,用GGB1的功能更多。 点击行项目,点击“新建替换”保存 点击新建YXL7331,点击…

【HCIP】生成树--STP

一、STP 1.产生背景 在星状拓扑或者树形拓扑中,当某个设备或者某条链路出现故障,就会导致数据不能正常转发,出现单点故障的问题。 为了防止出现单点故障,一般需要环形拓扑来保证链路的冗余性,当某条链路出现故障&…

OpenEuler 安装mysql

下载安装包 建议直接使用在openEuler官方编译移植过的mysql-5.7.21系列软件包 参考:操作系统迁移实战之在openEuler上部署MySQL数据库 | 数据库迁移方案 | openEuler社区官网 MySQL 5.7.21 移植指南(openEuler 20.03 LTS SP1) | 数据库移植…

天气插件和antv图表组件库的使用

目录 天气插件 antv组件库 特性 数据映射 data xField yField 图形样式 point state 图表组件 label tooltip 图表交互 添加交互 天气插件 网站:天气预报代码_天气预报插件_免费天气预报代码(插件)调用——天气网 (tianqi.com) 挑选想要的样式,点击 …

phpspreadsheet导出excel自动获得列,数字下标

安装composer require phpoffice/phpspreadsheetuse PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Writer\Xlsx; use PhpOffice\PhpSpreadsheet\Style\Border;$spreadsheet new Spreadsheet(); $sheet $spreadsheet->getActiveSheet();//从65开&a…

KCP协议

1、什么是kcp协议 了解kcp协议之前先回顾一下传输层的两大协议TCP和UDP。 kcp是一个快速可靠协议(也可以叫udp的可靠性传输)。结合了tcp的可靠性和udp的传输速度等优点,能以⽐ TCP浪费10%-20%带宽的代价,换取平均延迟降低 30%-40%…

学无止境·运维高阶⑦Docker进阶一(构建个人网盘)

Docker进阶一 1、使用mysql:5.6和 owncloud 镜像,构建一个个人网盘。1.1 拉取镜像1.2 创建容器1.3登录查看 1、使用mysql:5.6和 owncloud 镜像,构建一个个人网盘。 1.1 拉取镜像 [rootnode3 ~]# docker pull mysql:5.6 [rootnode3 ~]# docker pull own…

OpenCV为老照片,黑白照片增加色彩

Colorful Image Colorization 图片的颜色上色,主要使用到了CNN卷积神经网络,作者在ImageNet数据集上进行了大量的训练,并将此问题使用在分类任务中,以解决问题的潜在的不确定性,并在训练时使用颜色重新平衡的损失函数方…

秒杀系统的业务流程以及优化方案(实现异步秒杀)

先看基本的业务流程 那么我们可以看到整个流程都是一个线程来完成的,这样的话耗时还是很长的,那么可不可以采用多线程去实现呢? 首先我们要思考怎么对业务进行拆分,可以想象一个我们去饭店点餐,会有前台接待&#xff…

使用ChatGPT一键生成思维导图

指令1:接下来你回复的所有内容,都放到Markdown代码框中。 指令2:作为一个Docker专家,为我编写一个详细全面的Docker学习大纲,包括基础知识、进阶知识、项目实践案例,学习书籍推荐、学习网站推荐等&#xf…

curl --resolve参数的作用

之所以会有这样的操作,是因为域名一般对应的都是一个反向代理,直接请求域名,反向代理会将流量随机选一台机器打过去,而无法确保所有的机器都可用。所以直接用ip。 在 curl 命令中,--resolve 参数用于指定自定义的主机名…

业务系统架构实践总结

我从2015年起至今2022年,在业务平台(结算、订购、资金)、集团财务平台(应收应付、账务核算、财资、财务分析、预算)、本地生活财务平台(发票、结算、预算、核算、稽核)所经历的业务系统研发实践…

pycharm添加虚拟环境以及虚拟环境安装pytorch

file、settings、interpreter、add interpreter、add local interpreter 记住不要勾选inherit,不然会把主环境的东西继承到虚拟环境。 创建前可以先点existing看看有没有已经建好的虚拟环境 有的时候pycharm有问题,创建了虚拟环境没有显示。找一个.py文…

嵌入式底层驱动需要知道的基本知识

先说结论,能,肯定能,必须能! 但是,问题重点在于坚持,程序员这一行 ,下班回家一般都要10点了,再刷两个小时枯燥的学习视频,我想大多数人是坚持不下来的。 但是&#xff…

vue3+ts+uniapp小程序端自定义日期选择器基于内置组件picker-view + 扩展组件 Popup 实现自定义日期选择及其他选择

vue3ts 基于内置组件picker-view 扩展组件 Popup 实现自定义日期选择及其他选择 vue3tsuniapp小程序端自定义日期选择器 1.先上效果图2.代码展示2.1 组件2.2 公共方法处理日期2.3 使用组件 3.注意事项3.1refSelectDialog3.1 backgroundColor"#fff" 圆角问题 自我记…

计算机视觉 – Computer Vision | CV

计算机视觉为什么重要? 人的大脑皮层, 有差不多 70% 都是在处理视觉信息。 是人类获取信息最主要的渠道,没有之一。 在网络世界,照片和视频(图像的集合)也正在发生爆炸式的增长! 下图是网络上…

Spring MVC 学习总结

学习目标 了解 Spring MVC 是什么,为什么要使用它或者说它能解决什么问题,其与 Spring 是什么关系。理解为什么配置 Spring MVC 的前端控制器的映射路径为 “/” 会导致静态资源访问不了,掌握怎么处理这个问题。掌握基于注解方式使用 Spring…
最新文章