当前位置: 首页 > 科技观察

一个Java对象回忆录:垃圾收集

时间:2023-03-12 00:03:59 科技观察

一个对象的诞生“你醒了!”,我迷迷糊糊中听到一个声音,我睁开眼睛,发现一个小伙伴正在看着我。“这是哪里,你是谁?”“这里是堆区,我是Ajax对象,叫我小A。”我慢慢坐起来,环顾四周,这里住着许多形形色色的物体,远处有许多线程在忙碌,好热闹啊!“你好,我刚睡醒,还不知道自己是什么对象。”“很简单,我看看~~哦,原来你是一个APIController对象。”小A摸了摸我的头。“你怎么知道?”“这里头上有一个64位的Klass指针,这里,往这个方向看,里面记录了你所属的类信息,看,那里写着APIController。”听他一说,我才发现脑子里有两个64bit的字段。“喂,小A,旁边的64位数字是什么意思?”“那个叫MarkWord,是我们Java对象的门面,里面的信息很重要,你要好好保管,它就在这里……”MinorGC突然不知从哪里传来一连串的报警声,然后听到广播:“注意所有线程,请进入安全点等待,注意所有分区,启动一次MinorGC”当我听到广播站起来时莫名紧张。不知为何,远处那些忙碌的丝线,仿佛被定住了一般,全都停止了手上的动作。只有少数几人还在活动,这些线叔看起来和他们有些不同,几人就朝我们这边走了过来。“这个是来做什么的?”我向小A询问了情况。“不知道,我比你出生没多久,这种情况还是第一次见。”小A显得有些慌张。不多时,一条凶猛的管理员帖来了,拿着喇叭喊道:“听着,伊甸区的所有人,念名字的时候都站起来。”说完,他们开始一一点名。被叫,又怕不叫。看了半天,终于听到了我和小A的名字,我们都颤抖着站了起来。没多久就看完了,看了看,只有几个站着,心里有些不爽。“谁念名字就跟我来,剩下的交给我的助手。”说完,众人纷纷跟在他的身后,开始行动起来。在路上,我们遇到了另一个团队并加入了我们。“喂,兄弟,你叫什么名字?你是哪个单位的?”小A兴致勃勃地上去和伙伴聊天。“叫我小B,我们这波是SurvivorFrom区的,你们是Eden区的,我半小时前还在那边。”这个自称小B的也很随和。“嗨B哥,我们去哪?”我也上前说了些什么。“前方是幸存者区。”“我们是怎么被挑出来的?”“这里的管理员会用一个叫GCRoots的对象,找出所有还存在引用关系的对象,我们是幸存者。”我们仍然有价值。”“剩下的对象呢?”“它们的命运可能悬而未决,因为没有其他对象引用它们。需要清理一下,给它们腾出地方。”我心知肚明,边走边担心,很快就到了传说中的SurvivorTo区域,管理员安排我们坐下,“这里好小啊”不对,比起你原来的伊甸园,这里只有八分之一那么大”,我一转身,路上遇到的小B竟然就在我和小A旁边,真是巧。“哎,小B哥,我们折腾这么多干什么?”“这叫垃圾回收GC。你开始停留的地方叫做伊甸区,所有的物体都在这里诞生。我们所处的地方是一个叫做Java虚拟机世界的地方,程序员只是创建对象,并不关心释放对象。东西越来越多,伊甸园区域放不下,腾出地方来也是理所当然的。”我和小A都点了点头,庆幸躲过一劫,一抬头,不知什么时候,那些固定的线又开始工作了。“还没恭喜你呢,你又大一岁了。”小B拍了拍我们俩的肩膀,我们面面相觑,一脸问号。“这从哪里开始?”小A先开口。“你们头上MarkWord的第3到第6位记录了你们的年龄,一次GC之后,你们就老了一岁!”我们面面相觑,再看看小B的GC年龄位置,已经是15岁了。“B哥,难怪你见多识广,年龄这么大,咦,这就是说GC的年龄只有4岁,而且最大也只能是15岁,要是你以后再来GC,别太大了吧?”,看着小B的脑袋,我陷入了沉思。“如果我能熬过另一次GC,我就进入老年代区,我就不能再跟你们玩了。”小B眨巴着眼睛看着我们。“前辈,那是什么地方,我们不能去吗?”“都说是老一代了,是我这种老人们去的地方,你们这些新人还是要在SurvivorTo区和SurvivorFrom区转一圈,再过几轮就可以了等你到了我这个年纪就过去了。”“啊,怎么这么麻烦,为什么要设置那么多区?”小A焦急的问道。小B把手搭在小A的肩膀上说道:“这里的管理员使用了标记-复制算法来清理空间,所以需要在伊甸园区域之外另设一个地方来接收复制后存活的对象。”“那就加一个幸存者区就够了,何必再做两个幸存者区呢?”我也问了一个问题。小B把另一只手搭在我的肩膀上,“这是为了让存活的对象在这里反复循环,不要急着跑到老年代区。”“那为什么Survivor比Eden小那么多呢?”,我继续追问,“根据他们的统计,98%的对象都熬不过一轮GC,剩下的只有一小部分。而这两个中的一个幸存者区必须是空的,太大的话就太浪费了。”听着小B的话,我们俩都陷入了沉思。过了一会儿,广播再次响起:“注意所有线程,请进入安全点等待,注意所有分区,启动MinorGC”,刚刚平静的心再次悬空。管理员又开始点名了。这次我和小B都被叫到了,但是没有听到小A的名字。我们告别了小A,离开了SurvivorTo区域,走到了岔路口。小B也跟我道别:“再见朋友,有机会的话,老一辈等你回来再相聚。”然后我就只剩下目标了,我跟着陌生的目标队伍来到了SurvivorFrom区域,这个区域和刚才的To区域差不多大小,但是队伍比之前的要小很多。我来到自己的位置坐下,看了看头顶的GC年龄,我2岁了。Finalizer对象没有熟悉的朋友,孤零零的发呆,等待着线程来找我。突然,有人拍了拍我的肩膀。回头一看,是气喘吁吁的小A。“你不是没有被点名,没有人再提到你,没有被清理干净吗?”再次看到小A,我有点不敢相信。“刚才真的很危险,吓死我了,没想到事有转机!”“发生了什么,告诉我!”,我迫不及待地想知道这一切到底是怎么回事。小A喘了几口气,继续说道:“你刚走,管理员又拿出了一份名单,上面居然有我的名字,我打听了一下,发现还有一个Finalizer对象还在引用我~”奇怪,不是说没有对象吗,怎么又弹出一个Finalizer对象?这是什么东西?“后来我看到了Finalizer对象,一开始离我们不远,他说是因为我所属的类重写了finalize方法,我出生的时候他也出生了,一直持有我的reference。”“后来怎么样了?”我继续追问。”后来他被管理员放到了一个ReferenceQueue队列中,他们把那个地方叫做F-Queue监狱。等待一个叫Finalizer的线程叔叔处理,通过Finalizer对象调用我的finalize方法,之后我们切断开我们之间的联系。”“他要倒霉了!不过还好,他救了你一命。”“初一我能躲,十五天我躲不过,现在连Finalizer对象都不引用我了,下次GC,我肯定死定了”小小A说完就低下了头。“别想那么多,做伴侣最重要的是开心,说不定下次我会陪你走到最后。”刚聊完,熟悉的广播又回来了:“注意所有线程,请进入安全点等待。注意所有分区,启动一次MinorGC”很快,管理员读到了我的名字,看来我还是可以的存活。最后,管理员奇迹般的读到了小A的名字。“小A,你听到没有,有人在引用你!”我高兴地对小A说,小A用力地点点头。“我明白了,一定是finalizer线程在执行我的finalize方法的时候把我和某人联系起来了,对,一定是这样的!”我们又一次从To区来到了From区,这次少了很多老面孔,倒是有很多来自Eden的新面孔。接下来的一段时间里,我们在这里转了好几圈,终于看到头上的年龄标记逐渐变成了15岁。FullGC没多久,广播再次响起,我和小A幸运地再次被点名。事后,管理员检查了我和小A,发现我们超龄了,直接开车把我们开到一条新路上。知道前方就是传说中的晚年。来到这个陌生的地方,环顾四周,比我住的Eden区、From区、To区都大,里面的东西很多,密密麻麻,但好像没有一个是省油的灯.毕竟,和伊甸区那些可爱的新人相比,能来这里的都是老油条。我们两个找到了自己的位置,坐下开始聊天。这时,不远处来了一个身影,走近一看,正是之前的小B。“咦,这不是小A吗?记得你被清理干净了,你怎么来了?”B哥对小A的出现有些意外,随后小A也和小B聊起了之前的惊险经历~聊着聊着,管理员突然进来,圈了一大片空地,还创造了一个巨大的目的!所有的物体都被震撼了!“B小兄弟,这哥们是什么来历,空降,直接上古!”我好奇的问道。“没办法,谁这么大,伊甸园区域装不下,要不给他复制太费力了,所以我直接安排在这里了,也不是非要熬过去不可的。”少量。”“Attentionallthreads,Pleaseenterthesafepointandwait,关注每个partition,开始FullGC”,熟悉的广播再次响起,不过这次是FullGC。“看来记忆很紧啊!”小B叹了口气。管理员又开始点名了,这一次,运气不再眷顾小A了。未完待续~~彩蛋一个线程小姐姐向我走了过来。“嗨,你好小子,我是线程3002,现在给你加锁,你别动,我查一下你的MarkWord”“锁位是01,好!让我再看看偏向锁位,啊!是1,不好”小姐姐皱眉道。想知道接下来会发生什么,敬请关注后续精彩内容……