Java垃圾回收机制
堆内存区域划分:
我们可以把Java垃圾回收机制比作是一个公司的仓库,这个仓库里面有3个小仓库,分别名称为新生代,老年代,永久代(方法区,元空间),在新生代里面又可以划分3个子仓库,分别为e0(Eden),s0(Survivor From ),s1(Survivor To).
GC Roots
公司把所有的货物都标记清楚,那些要存放,那些将要被清除,搬移。同时,需要记录着这些货物的关系,比如A货物的搬移或清除,需要先将B货物搬移或清除。这样货物的搬移清除就会形成一个完成的链条。
分配内存:
当 货物(对象)到达时,我们总是先将货物送到新生代这个仓库的子仓库e0区,当e0区装不下货物时,就会触发一次回收(Minor GC)。我们需要把没有回收干净的货物放到s0区。如果e0再次满了,就会再次触发一次回收。把没有回收干净的货物放到s1区,然后清空e0区。我们可以把e0,s0,s1通知一定的比例设置他们的空间大小,这样便于货物的存放。
大对象分配
如果我们的货物的空间大于了e0区的空间,那么我们直接将货物放到老年区
多线程:
在分配e0区时,为了加快分配的速度,我们可以同时雇佣N个工人,让他们按照一定的规则进行分配摆放。
Full GC:
当执行一定次数的回收,如果s0,s1区也装不了货物了,这个时候,可以让货物放到老年代的仓库。因为仓库空间整体是有限的,如果老年代空间也不足以清理干净了。那么就会导致一次垃圾大回收。
回收算法
标记-清除
我们将待回收的货物进行标记方便快速清理仓库的货物
标记-整理
我们将待回收的货物进行标记,同时把待回收的货物整理到一起。
复制
我们将仓库分为2块空间,如果货物保留下来,就将一个的货物搬到另一边。然后在把其他货物都清除掉。
收集器
安全检查点
我们去仓库清理货物的时候,需要在一个安全的时候去整理。比如货物刚刚运送过来(用户线程还没有执行完毕),需要等到运送完毕后,才可以清除货物
单线程
公司只有一个人在仓库里面把清理货物
多线程
仓库同时有N个工人清理货物
并发
仓库同时有货物搬入,同时在清除货物的过程
G1
我们不在将整个仓库按照**新生代,老年代,永久代(方法区,元空间)**来划分仓库的空间。可以想象成我们把每个小仓库的门或者强推倒了。没有门了。这样把原来的新生代,老年代,增加新的humongous区。专门存放巨大的货物。