小明有个强迫症,每天回家都会去商店买一瓶饮料。饮料喝完了,垃圾直接扔在房间地上。
久而久之,房间被垃圾塞满了,需要清理。
现在小明有如下选择:
1.直接清理垃圾,但由于其他各种物件原封不动摆放,使得房间还是很杂乱,空间利用率低,而且垃圾一个个捡起来也很麻烦。
2.把有用的东西整理出来移到另一个房间,然后再清理垃圾。这样只需要整理一次物品,就能一次性扫除所有垃圾,但这需要小明拥有两个房间。然而小明只有一个房间,所以他只能把自己的房间改造成两个隔间。这样一来虽然能够实现小明的想法,但是房间也更容易满了,而且每次等这个隔间满了都要把所有物品搬到另外一个隔间,麻烦。
3.在房间内画一条白线,把垃圾和有用的东西分开放置在白线两边,再清理垃圾。这种方式也是可行的,但这非常考验小明的边界感,因为我们都知道小明强迫症非常严重。所以小明每次整理房间都非常累,需要先整理好所有物品放在一边,再一个个捡起所有垃圾放在另一边。
那还有更好的方式吗?
有没有这样一种可能,小明直接买一个垃圾桶,这样就不用乱扔垃圾了?(笑)
小明异想天开,将房间开辟成一大(20平米)一小(10平米)两个隔间,在小隔间里布置了一个拥有两个抽屉(1平米)的柜子,有用的物品放到抽屉里就好了。
一个月以后,小隔间第一次满了。
小明把有用的物品放到第一个抽屉里,清理房间。
两个月以后,小隔间满了。
小明把地上和第一个抽屉里经常用的物品取出来放到第二个抽屉里,再清理房间。
三个月以后,小隔间满了
小明把小隔间地上和第二个抽屉里经常用的物品取出来放到第一个抽屉里,再清理房间。
四个月以后。重复。
五个月以后。重复。
。。。。。
一年以后,小隔间再一次满了。
小明打开抽屉,发现两个抽屉也都快满了。
小明只好整理两个抽屉,把经常看的一些书籍和常用的物品搬到另一个房间。
这样,抽屉就空了一些。
那大隔间的垃圾呢?
算了,小明很懒。
大隔间,等满了再说吧。
(完)
小明为什么要这么麻烦呢?这跟提到的Java垃圾回收机制又有什么样的关联呢?
这里啊,就不得不提到垃圾回收传统的三种算法Mark Sweep标记清除算法、Copying复制算法和Mark Compact标记整理算法,也就是小明的前三种选择。
但是以上几种办法都有局限性,而且小明也很懒。
怎么办呢?
于是这里就有了Generational Collection分代收集算法。
分代收集算法指的是Java内存内部开辟了空间比例为10:20的一片小区域和一片大区域(小明的两个大小隔间),其中小区域又分为8:1:1三块区域(小隔间主要空间和两个抽屉)。小明住的这个10平米小隔间会经常性清理垃圾(Young Generation年轻代),而20平米大隔间则较少清理垃圾(Old Generation老年代)。等小明住的隔间垃圾满了之后,会把地上(Eden伊甸区)有用的物品整理到柜子的第一个抽屉(From区),再一次性清理地上的垃圾,这样房间就空了(Copying复制算法)。等下一次小隔间满的时候,就把地上和第一个抽屉里经常使用的物品整理到第二个抽屉(To区),第一个抽屉里剩下的物品不做处理,这样房间就又空了。如此循环往复,直到两个抽屉都满了为止,小明就会把抽屉经常用到的物品搬到大隔间,抽屉里的剩下物品因为经常用不到,就可以当作垃圾扔掉。
至于大隔间满了,因为大隔间里都是有用的东西,被当作垃圾的东西比较少,而且空间比较大,所以只需要直接捡起所有垃圾(Mark Sweep标记清除算法)并且整理物品(Mark Compact标记整理算法)就好了。
这样一来,小明就能做到空间的合理分配,经常收拾垃圾的区域就由原来的30平米缩小到了10平米,并且垃圾再也不用一个个捡,真正做到高效整洁。