经典面试题:聊一聊垃圾回收算法

关于垃圾回收算法的这道面试题,几乎是所有 3 年以上的 Java 面试中必问的题目,甚至有些好一点的公司会在校招时问到面试者。那么本文就系统的讲一下垃圾回收的算法,和 Hotspot 虚拟机执行垃圾回收的一些实现细节,比如安全点和安全区域等。

因为各个平台的虚拟机操作内存的方法各不相同,且牵扯大量的程序实现细节,所以本文不会过多的讨论算法的具体实现,只会介绍几种算法思想及发展过程。

垃圾回收算法

1、标记-清除算法

标记-清除算法是最基础的算法,像它的名字一样算法分为“标记”和“清除”两个阶段,首先需要标记出所需要回收的对象,标记完成后统一收集被标记的对象。

优点: 实现简单。

缺点: 产生不连续的内存碎片;“标记”和“清除”的执行效率都不高。

标记-清除算法执行过程图:

(本文图片来自《深入理解Java虚拟机》)

2、复制算法

复制算法就是将内存分为大小相同的两块,当这一块使用完了,就把当前存活的对象复制到另一块,然后一次性清空当前区块。

优点: 执行效率高。

缺点: 空间利用率低, 因为复制算法每次只能使用一半的内存。

3、标记-整理算法

也称标记-压缩算法,标记-整理算法采用和标记清除算法一样的对象“标记”,但后续不会对可回收对象进行清理,而是将存活的对象往一端空闲空间移动,然后清理边界以外的内存空间。

优点: 解决了内存碎片问题,比复制算法空间利用率高。

缺点: 因为有局部对象移动,相对效率不高。

标记-整理算法执行过程图:

4、分代收集算法

目前商用虚拟机都采用的是分代收集的算法,这种算法按照对象存活周期把内存分为几块,一般Java中分为新生代和老年代。把存活率低的对象分到新生代使用复制算法提高垃圾回收的性能,老年代则存放存活率搞的对象,使用标记-清除和标记-整理的算法,提高内存空间使用率。

新生代和老生代的具体介绍和参数配置,后续的文章会详细讲解。

垃圾回收执行细节

本节将详细的介绍一下HotSpot虚拟机在执行垃圾回收时的一些细节,目的是让读者更好的理解Java虚拟机。

HotSpot虚拟机: 它是Sun JDK和OpenJDK自定的虚拟机,也是目前使用最广泛的虚拟机。

垃圾回收流程: Java虚拟机在内存回收之前,为了保证内存的一致性,必须先暂停程序的执行,也就是传说中的Stop The World(简称STW),在使用可达性分析算法枚举GC Roots,标记出死亡对象,再进行垃圾回收。

垃圾回收遇到的问题: 那既然是要暂停程序的运行,就一定要保证停止的时间足够短,并且可控,不然带来的灾难将是毁灭性的。

解决方案: 显然HotSpot在设计的时候也考虑到了这个问题,所以在JIT编译的时候就会使用OopMap数据结构来记录栈和寄存器上的引用,这样虚拟机就直接知道了那些地方存放着对象的引用,如下图,为我编译String.hashCode()方法的部分本地代码:

可以看出,使用OopMap数据结构存储了普通对象的指针引用。

查看汇编的方法,启动命令窗体执行: java-XX:+UnlockDiagnosticVMOptions-XX:+PrintAssemblyYouTestClass

命令可能会报错: Couldnotload hsdis-amd64.dll;librarynotloadable;PrintAssemblyisdisabled

报错解决方法:使用编译好的hsdis.dll放到:jre安装目录\bin\server目录下即可,hsdis.dll地址地址:https://pan.baidu.com/s/1-D6u0gnUx291LXS3bHOorA

安全点(Safepoint)

在OopMap的协助下,HotSpot可以快速的完成GC Roots枚举,但导致OopMap内容变化的指令很多,而且如果给每个对象生成对应的OopMap,会造成大量额外的空间,这会导致GC成本很高,所以HotSpot只会在“特定的位置”生成对应的OopMap,这些位置就成为“安全点”。

HotSpot也并不是任何时刻都会停顿下来进行GC,只会在程序都到底安全点之后才会GC,所以安全点的设置不能太少,让GC等待时间太长,也不能太多增大运行时的成本。

安全点的两种线程中断方式

抢断式中断:不需要线程的执行代码去主动配合,当发生GC时,先强制中断所有线程,然后如果发现某些线程未处于安全点,恢复程序运行,直到进入安全点为止。

主动式中断:不强制中断线程,只是简单地设置一个中断标记,各个线程在执行时轮询这个标记,一旦发现标记被改变(出现中断标记)时,那么将运行到安全点后自己中断挂起。目前所有商用虚拟机全部采用主动式中断。

安全区域(Saferegion)

安全点机制仅仅是保证了程序执行时不需要太长时间就可以进入一个安全点进行 GC 动作,但是当特殊情况时,比如线程休眠、线程阻塞等状态的情况下,显然HotSpot不可能一直等待被阻塞或休眠的线程正常唤醒执行;此时就引入了安全区的概念。

安全区(Saferegion):安全区域是指在一段区域内,对象引用关系等不会发生变化,在此区域内任意位置开始GC都是安全的;线程运行时,首先标记自己进入了安全区,然后在这段区域内,如果线程发生了阻塞、休眠等操作,HotSpot发起GC时将忽略这些处于安全区的线程。当线程再次被唤醒时,首先他会检查是否完成了GC Roots枚举(或这个GC过程),如果完成了就继续执行,否则将继续等待直到收到可以安全离开的Safe Region的信号为止。

总结

前面讲的垃圾回收器算法属于基本功,要求面试者一定要熟练记忆的,而后面的垃圾收集器的执行细节如果加分项,如果都能融会贯通的话,Offer 就离你又进一步了。

【End】

查看更多面试题内容,请访问《Java最常见200+面试题全解析》,它包含的模块有:

  • Java、JVM 最常见面试题解析

  • Spring、Spring MVC、MyBatis、Hibernate 面试题解析

  • MySQL、Redis 面试题解析

  • RabbitMQ、Kafka、Zookeeper 面试解析

  • 微服务 Spring Boot、Spring Cloud 面试解析

扫描下面二维码付费阅读

关注下方二维码,订阅更多精彩内容。

转发朋友圈,是对我最大的支持。

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

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

相关文章

九、华为鸿蒙HarmonyOS应用开发之Java UI框架、常用Image组件使用

一、Image 二、Image组件实例测试 1.新建基于empty ability(Java)手机应用程序的ImageTest工程。运行出现如下结果 2.在Project窗口,打开“entry > src > main > resources > base > media”,添加4个图片至media文件夹下,以“pic1.jpg”、“pic2.jpg”、…

阿里面试,我挂在了第四轮……

可能每个技术人都有个阿里梦,我也不例外。最近准备跳槽,前一阵子在准备各种面试,也面了几个大厂,包括阿里。是的,最后我挂在了第四轮。这篇文章来总结一下我在阿里四轮的面试经历,希望能对读者有所启发。阿…

基于IP-PBX的VoIP系统解决方案

基于IP-PBX的VoIP系统解决方案目前,众多企业随着业务的扩张,开设了大量的分支机构,这样企业总分支机构以及分支机构之间的语音沟通是非常频繁,企业长途电话费用是企业经营成本中的一项巨大开支。现在互联网已非常普及,…

面试官:聊一下二分法

来源:cnblogs.com/luoxn28/p/5767571.html1、二分查找二分查找是一个基础的算法,也是面试中常考的一个知识点。二分查找就是将查找的键和子数组的中间键作比较,如果被查找的键小于中间键,就在左子数组继续查找;如果大于…

Delphi利用Windows GDI实现文字倾斜

2019独角兽企业重金招聘Python工程师标准>>> procedure TForm1.FormPaint(Sender: TObject);var FLogFont: tagLogFontW; hTempFont, hPrevFont: HFONT; //字体句柄 hTempDC: HDC; //设备描述表或图形设备句柄 TempString: string; //输出的文字begin FLogFont…

面试干货 | Java 能否自定义一个类叫 java.lang.System?

本文由读者 apdoer 投稿,apdoer 是一个极具钻研精神的 Java 猿,技术牛X头发茂盛! 博客地址:https://blog.csdn.net/m0_43452671缘起:一个面试题最近在上下班地铁刷博客,无意刷到一个面试题,号称很多程序员的烈士公墓:j…

mysql 数据库文件导入和导出、远程上传和下载数据库

1.打开数据库操作软件:Navicat Premium 15 中文版,登录测试连接! 2.打开本地mysql 数据库,新建数据库的名字必须和要导入的数据库名字一致。字符集和排 序规则按下图设置即可。

经典面试题 | 讲一下垃圾回收器都有哪些?

垃圾回收器有哪些?是一个高频的面试题,那本文就详细来解答这个问题。因为不同的厂商(IBM、Oracle),实现的垃圾回收器各不相同,而本文要讨论的是 Oracle 的 HotSpot 虚拟机所使用的垃圾回收器。常用垃圾回收…

十、华为鸿蒙HarmonyOS应用开发之Java UI框架、常用TabList组件使用

一、TabList和Tab 二、TabList组件实例测试 1.新建基于empty ability(Java

dotConnect for Oracle控件免费下载及使用方法

原文来自龙博方案网http://www.fanganwang.com/product/1330转载请注明出处dotConnect for Oracle完全基于ADO.NET方法,因此您完全可以采用标准ADO.NET数据提供的方法来使用它。是一款为Microsoft .NET Framework提供直接Oracle数据库连接的数据发生器控件。 具体功…

面试官:谈谈数据库连接池的原理

来源:https://dwz.cn/oUF6pKOW这次我们采取技术演进的方式来谈谈数据库连接池的技术出现过程及其原理,以及当下最流行的开源数据库连接池jar包。一、早期我们怎么进行数据库操作1、原理一般来说,Java应用程序访问数据库的过程是:①…

php调用twitter api

今天做了一个关于调用twitter api来同步twitter信息到自己网站的功能,虽然是比较简单的功能,着实花费了我不少时间。网上有很多关于twitter api调用的方法,我试了几个都没有成功,貌似需要Oauth验证,这个跟微信开发类似…

8种常见SQL错误用法,你犯过几个?

来源:https://yq.aliyun.com/articles/72501高考和端午小长假一溜烟的功夫就全过完了,新的一周,让我们迎着清晨的阳光,继续前行。1、LIMIT 语句分页查询是最常用的场景之一,但也通常也是最容易出问题的地方。比如对于下…

51单片机 16*64LED单红点阵屏驱动测试,上位机改字软件免费版

public.h #ifndef __PUBLIC_H__ #define __PUBLIC_H__#include "STC12C5A60S2.h" #include <intrins.h> #include <string.h>//包含memset函数#define UCHAR unsigned char #define UINT unsigned int #define TRUE 1 #define FALSE 0#define LEDON 0…

cocos2dx基础篇(2)——Win32移植到Android

【安装工具】JDKEclipse 或直接下一个 ADT集成开发工具SDKNDK9rADTCDT安装方法自行百度。【正文】1、由 Cocos2D-X 和 VS2010 环境配置——1 中提到的python方法&#xff0c;创建新项目。然后将你开发好的win项目相应的文件Classes和Resources文件夹里的东西分别拷贝到刚创建的…

HR一般不会告诉你的八大真相

我们都是经历过招聘面试的&#xff0c;HR那种微笑很深奥很捉摸不透想必你也见过&#xff0c;但是就是猜不透是什么意思对吧&#xff1f;那么&#xff0c;就赶紧来看看这些HR一般不会告诉你的真相吧!1.求职实际上是一个难以公平的被拒绝过程公平的环境下求职?从HR的角度来说&am…

北京爱情故事-经典语录

2019独角兽企业重金招聘Python工程师标准>>> 小母牛追小公牛&#xff0c;牛逼急了&#xff01; 牛就一个字&#xff0c;我只说一次&#xff01; 男人在外面对女人有多坏&#xff0c;回家就对老婆有多好。——王学兵 结婚十年后&#xff0c;我终于发现其实人生上半…

memcache、redis原理对比

blog.csdn.net/suifeng3051/article/details/23739295一、问题&#xff1a;数据库表数据量极大&#xff08;千万条&#xff09;&#xff0c;要求让服务器更加快速地响应用户的需求。二、解决方案&#xff1a;1.通过高速服务器Cache缓存数据库数据2.内存数据库这里仅从数据缓存方…

我被面试官给虐懵了,竟然是因为我不懂Spring中的@Configuration

作者 l cxuan来源 l Hollis&#xff08;ID&#xff1a;hollischuang&#xff09;现在大部分的Spring项目都采用了基于注解的配置&#xff0c;采用了Configuration 替换标签的做法。一行简单的注解就可以解决很多事情。但是&#xff0c;其实每一个注解背后都有很多值得学习和思考…

jQuery中的.bind()、.live()和.delegate()之间区别分析,学习jquery

2019独角兽企业重金招聘Python工程师标准>>> DOM树 首先&#xff0c;可视化一个HMTL文档的DOM树是很有帮助的。一个简单的HTML页面看起来就像是这个样子&#xff1a; 事件冒泡(又称事件传播) 当我们点击一个链接时&#xff0c;其触发了链接元素的单击事件&#xff0…