当前位置:首页 > 问答 > 正文

我跟面试官聊垃圾回收的时候,脑子里其实是这么想的,虽然说得不太连贯但大概就是这样

行,那我现在就坐这儿跟面试官聊垃圾回收呢,脸上赔着笑,嘴里说着“可达性分析”、“分代收集”这些词儿,听起来好像挺懂行的,但其实我脑子里啊,跑的全是另一套画面,面试官一开口问“你了解JVM的垃圾回收机制吗?”,我第一个冒出来的念头其实是:这不就跟我们小区收垃圾的老王头儿干的活儿一模一样嘛!

我先想到的是老王头儿,他每天凌晨四点,推着那辆哐当响的绿皮三轮车,挨个楼栋转悠,他的任务就是把这堆混乱的东西整理清楚,把还有用的(比如偶尔扔出来的旧椅子,他捡回去修修还能坐)和真没用的烂菜叶子分开,然后把真正的垃圾清走,腾出地方,让新一天的垃圾有地儿可扔,GC干的不就是这事儿吗?它得在某个大家都歇着的时候(就是那个听起来很专业的“Stop-The-World”时刻),跑来检查内存这片小区,看看哪些对象还在被“用着”,哪些已经没人要了,是垃圾了,然后清理掉。

面试官点点头,可能觉得我入门了,接着问:“那你说说分代回收是怎么回事?”我嘴上开始掰扯新生代、老年代,心里想的却是我们小区的垃圾桶分布,我们小区门口摆着几个特小的、带盖子的新垃圾桶,那是“新生代”,为啥小?因为居民临时扔个烟头、擦嘴的纸巾,这种垃圾来得快,去得也快,一会儿就满了,所以清洁工(也就是GC)跑这儿跑得最勤快,动不动就来清一次,动作也麻利,像“Minor GC”,唰一下,很快啊,清完就走,不影响大家进出。

那“老年代”呢?就是小区角落里那几个巨大的、绿色的铁皮垃圾箱,那儿扔的都是大件儿,比如旧衣柜、破床垫,或者攒了不知道多少年的旧报纸,这些东西吧,不是说一天两天就能攒出来的,都是经过时间考验的,“存活”了很久才被扔出来的,所以清洁工一般不爱动它们,动静太大了,清一次得叫大卡车(Full GC),费时费力,整个小区通道可能都得暂时拦一下,大家扔垃圾都得等着,这不就跟JVM里,那些经过好几次新生代GC都没被回收掉,最终晋升到老年代的对象一个道理嘛?处理它们成本高,所以GC策略很谨慎。

面试官可能觉得我比喻得还行,追问道:“不同的垃圾回收器,比如G1,你怎么理解?”这时候我脑子里的画面升级了,从我们小区变成了一个大型的现代化工业园区,G1回收器不像老王头儿那样顺着一条路扫荡过去(串行回收),也不像好几个老王头儿分区同时扫(并行回收),它更像一个聪明的园区物流机器人系统,这个系统把整个内存园区划分成好多块大小固定的区域(Region),它心里有个实时地图,时刻监控着哪块区域里的垃圾最多(就是垃圾密度最高),它下次清理的时候就优先去扫荡那块地,因为这样“性价比”最高,用最少的力气清出最多的空间,这就叫“停顿时间可控”,我清理的都是垃圾扎堆的地方,效率高,对园区正常运作的影响还小。

说到“垃圾”,怎么定义啥是垃圾呢?面试官要是问这个,我脑子里立马出现我我妈,我小时候,我媽收拾我屋子,判断我桌上东西要不要扔的标准,绝对不是这东西看起来旧不旧,而是“我还有没有在用”,哪怕那张纸我已经画得乱七八糟,但只要我第二天还要接着画,我妈就绝不会扔,可一旦我考上初中,那些小学的课本就算崭新如初,她也觉得是垃圾,可以卖废品了,这就是“可达性分析”最朴素的道理啊:只要还有一条途径(比如我这个“主线程”)能访问到这个对象,它就不是垃圾,反之,就算你这个对象本身完好无损,但已经没有任何办法能访问到你了,那对不起,你就是垃圾,得被回收,什么对象常被误伤?就是那种循环引用,好比屋里一个旧风筝线轴缠着另一个,它俩互相指着对方说“他还在用我呢!”,但其实我已经忘了这俩的存在了,我妈(GC)一来,才不管你们内部的复杂关系,一看跟我(GC Roots)没联系了,统统扔掉。

面试官可能会问“为什么会有内存泄漏?”这个我太有体会了,就是我爸那个舍不得扔的破工具箱,那个箱子本身已经锈得打不开了,里面的工具也早就不能用了,但我爸总觉得“说不定哪天能用上”,就一直把它塞在阳台最角落里,它占着地方,导致新的储物箱没地儿放,这在程序里,不就是某些对象已经不会再被使用了,但由于还被某个长期的引用(比如一个静态Map)指着,GC以为它还有用,不敢回收,就这么一直占着内存茅坑不拉屎吗?这就是典型的内存泄漏,不是GC不干活,是我们自己创造了“垃圾”却还给它贴了个“有用”的标签。

所以啊,面试官老师,您看,您问的那些高大上的原理,底层逻辑其实就这么点事儿,全是生活,我可能没法把每个算法的名字和参数都背得一字不差,但垃圾回收这事儿该怎么想、为什么这么设计,我心里门儿清,它不就是个兢兢业业的社区清洁工,加一个有点智慧的园区物流系统,再加点我妈收拾屋子的决断力,以及要小心提防我爸那种“舍不得”造成的囤积癖嘛,我这通比喻可能不够专业,但道理,我觉得是这么个道理。

我跟面试官聊垃圾回收的时候,脑子里其实是这么想的,虽然说得不太连贯但大概就是这样