面试常见之JVM垃圾回收机制GC详解(1),跨越速运java面试经历简述

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
img

正文

俗话说的好:“世界上没有免费的午餐”,是需要成本滴~

  • 首先资源付出的成本(CPU,内存……)支持垃圾回收机制能进行工作

  • GC对于内存的回收即时性没有那么高(虽然能在一定的时间内进行回收,但也不是不用了立刻就回收,有一定的延迟)

  • GC中存在一个致命的问题:STW问题(stop the word)

什么是STW问题?

就是当GC工作的时候,正常的业务代码可能无法执行,必须要等到GC工作完毕。对于服务器来讲,一旦服务器出发了GC,就可能导致正常代码无法执行(会出现卡顿),因为服务器可能会不断接收到请求,那么就会造成请求的积压,可能导致请求到一半就停止,或者是刚刚接收到请求而无法处理请求,直接造成用户体验的影响。

②. C/C++不是调用free/dalete函数就释放了吗?为什么还会出现“内存泄漏“问题?

答:上面提到需要在合适的时机进行释放,虽然内存内存的申请时机一般都是明确的,但是这个合适的释放时机是比较模糊的

1.2.对于 Java 而言

有GC机制,只管申请内存,无需关注内存的释放,而且可以很大程度上规避内存泄漏的问题(也不是完全没有)

2.GC要回收哪些内存?

============

1.PC程序计数器 / 栈 :都不要 GC 回收,因为他的释放时机很明确,随着线程的创建而申请内存,随着线程的销毁而释放。

2.常量池 / 方法区 :GC也不需要太关心,因为它占用的空间比较小,数据也很少会失去作用,如果对其进行GC,回收内存的性价比也不高(比如:打扫一个干净的小房间,即便你在怎么去打扫,也扫不出多少灰尘)

3.堆:GC主要回收的区域,堆的内存区域也很大,申请又很频繁(因为每次new对象都会在堆上申请内存)

2.1.堆上的内存分布

在这里插入图片描述

所谓的 “回收内存” => “回收对象”

GC工作的本质其实就是回收对象,以对象为基本单位(更方便),把不需要使用的对象找出来,回收掉即可,回收对象就会释放内存。

3.如何标记垃圾?

=========

所有的垃圾回收大体都是遵循以下两个步骤:

1.标记:找出哪个对象是垃圾

2.回收:把标记的垃圾对象释放

标记的方式有很多种,这里讲述两种:引用计数 和 可达性分析

一般来说像python PHP 语言会用到”引用计数“,而Java一般使用第二种”可达性分析“。

3.1.引用计数

引用 的方法很简单,判定的效率也比较高,大部分情况都是一个不错的算法,即给对象增加一个引用计数器,每当有一个地方引用它时,计数器就+1;当引用失效时,就-1;任何时刻计数器为0的对象就是不能再被使用的,即对象已”死“

在这里插入图片描述

引用计数的缺陷——”循环引用“

主流的JVM中没有选用引用计数法来管理内存,主要是因为引用计数法无法解决对象的循环引用问题

如:

class A{

A ret = null;

}

public class Demo2 {

public static void main(String[] args) {

A a1 = new A();

A a2 = new A();

a1.ret = a2;

a2.ret = a1;

}

}

分析:

在这里插入图片描述

3.2.可达性分析

Java不采用”引用计数法"来判断对象是否已”死“,而是采用"可达性分析"来判断对象是否存活。

算法核心:通过一些列成为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索走过的路径称之为“引用链”,当一个对象到GC Roots没有任何的引用链相连时(从GC Roots到这个对象不可达),证明此对象时不可用的。

在这里插入图片描述

上图如果看不太懂,可以看下图,如:

在这里插入图片描述

**总结:**可达性分析,就是从GC Roots开始进行遍历,看到哪些对象是能够被访问到的(某个对象在遍历过程中只要被访问一次,也可以被访问多次),那么剩下的就是垃圾。实际对象之间的相互引用关系不是简单的树形结构,而是“图”结构

可达性分析可视为GC Roots的对象包括以下几种

  • 栈上的局部变量表中的引用(每个程序有多个线程,每个线程有自己的栈,每个栈又有很多层栈帧,每层栈帧又有很多局部变量,这些内容试试GC Roots的一部分)

  • 常量池中引用指向的对象

  • 方法区中静态引用指向的对象

Java对引用的概念做了扩充,将引用分为强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)和虚引用(Phantom Reference)四种,这四种引用的强度依次递减。

  • 强引用:既能用于找到对象,也能决定对象的生死

  • 软引用:能用于找到对象,能够一定程度上的决定对象的生死(能保对象一时,内存如果充裕,不会回收软引用指向的对象,但是如果内存紧缺了,就会回收该对象)

  • 弱引用:只能用于找对象,不能决定对象的生死

  • 虚引用:不能用于找对象,也不能够决定对象的生死,只能在对象消亡之前,收到通知做一些善后工作

3.3.回收方法区垃圾

目前很多框架大量使用到反射,方法去会被加载很多类,那么此时也是需要回收的

方法区(永久代)的垃圾回收主要内容:废弃常量和无用的类(类对象(类的卸载)=>(和类的加载对应))

判定一个类是否是"无用类"则相对复杂很多。类需要同时满足下面三个条件才会被算是"无用的类" :

  • 1.该类的所有实例已经被报备回收了

  • 2.加载该类的类加载器也已经被回收了

  • 3.该类的类对象没有在任何地方使用(其他的代码也没有在通过反射来使用这个类对象)

JVM可以对同时满足上述3个条件的无用类进行回收,也仅仅是"可以"而不是必然。在大量使用反射、动

态代理等场景都需要JVM具备类卸载的功能来防止永久代的溢出。

讲完了垃圾是如何标记的,下面我们谈谈垃圾又是如何回收的呢

4.如何回收垃圾

========

4.1.标记 - 清除算法

将需要回收的对象全部标记出来,标记完成后将所有已标记的对象统一回收

在这里插入图片描述

标记 - 清除算法的缺陷

  1. 空间问题:我们不难发现上图清除垃圾之后,可分配的内存空间并不是连续的,这就是产生了“内存碎片问题”,空间碎片太多可能会导致以后在程序运行中需要分配较大对象时,无法找到足够连续内存而不得不提前触发另一次垃圾收集

  2. 效率问题:标记和清除这两个过程的效率都不高

4.2.标记 - 复制算法

能够解决内存碎片问题

"复制"算法是为了解决"标记-清理"的效率问题。它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这块内存需要进行垃圾回收时,会将此区域还存活着的对象复制到另一块上面,然后再把已经使用过的内存区域一次清理掉。这样做的好处是每次都是对整个半区进行内存回收,内存分配时也就不需要考虑内存碎片等复杂情况,只需要移动堆顶指针,按顺序分配即可。此算法实现简单,运行高效

在这里插入图片描述

总结

三个工作日收到了offer,头条面试体验还是很棒的,这次的头条面试好像每面技术都问了我算法,然后就是中间件、MySQL、Redis、Kafka、网络等等。

  • 第一个是算法

关于算法,我觉得最好的是刷题,作死的刷的,多做多练习,加上自己的理解,还是比较容易拿下的。

而且,我貌似是将《算法刷题LeetCode中文版》、《算法的乐趣》大概都过了一遍,尤其是这本

《算法刷题LeetCode中文版》总共有15个章节:编程技巧、线性表、字符串、栈和队列、树、排序、查找、暴力枚举法、广度优先搜索、深度优先搜索、分治法、贪心法、动态规划、图、细节实现题

最新出炉,头条三面技术四面HR,看我如何一步一步攻克面试官?

《算法的乐趣》共有23个章节:

最新出炉,头条三面技术四面HR,看我如何一步一步攻克面试官?

最新出炉,头条三面技术四面HR,看我如何一步一步攻克面试官?

  • 第二个是Redis、MySQL、kafka(给大家看下我都有哪些复习笔记)

基本上都是面试真题解析、笔记和学习大纲图,感觉复习也就需要这些吧(个人意见)

最新出炉,头条三面技术四面HR,看我如何一步一步攻克面试官?

  • 第三个是网络(给大家看一本我之前得到的《JAVA核心知识整理》包括30个章节分类,这本283页的JAVA核心知识整理还是很不错的,一次性总结了30个分享的大知识点)

最新出炉,头条三面技术四面HR,看我如何一步一步攻克面试官?

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
总结了30个分享的大知识点)**

[外链图片转存中…(img-mXIGZqki-1713185373535)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-479WF6ye-1713185373536)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 9
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值