JVM四种垃圾回收算法

一、标记-清除法

标记-清除法是最基础的垃圾回收算法,正如他的名字一样,先标记,再清除。

标记:对象回收会进行至少两次标记,当对象根据“根搜索算法”不可达时,对象会进行第一次标记,并进行一次筛选,筛选条件是“是否有必要执行finalize() 方法” 当对象没有覆盖finalize() 方法,或者finalize() 方法已经被虚拟机调用过,则认为没有必要执行finalize()方法,也就是说对象可以 go die 了。如果有必要执行,那么对象就会被放在一个F-Quene队列中,并由虚拟机创建一条低优先级的线程去执行。finalize()方法可以看成是虚拟机给对象一个实现“临死前的愿望”的机会,通过这个方法,对象可以进行最后一次机会的自救(重新与引用链上的对象进行关联),或者发表遗言(类似try-finally)进行最后一次动作。

标记-清除法有两个主要缺点:效率低,空间碎

效率低: 标记-清除法的标记和清除效率都不高

空间碎:使用标记-清除法进行清除,标记的对象清除后会产生大量不连续的内存碎片,当虚拟机需要为某个对象分配较大内存时,很有可能会由于找不到足够大的连续内存,而不得不提前触发另一次垃圾收集动作(垃圾收集是自动进行的)。

 

二、复制收集算法

复制收集算法是为了解决标记-清除算法的效率问题而产生的。他是将可用内存分成大小相等的两块,只使用其中的一块,当这一块的内存用完了,就将这块内存上存活的对象复制到另一块上面,然后把这块已使用的内存上面的空间一次性清理掉,这样便不存在内存碎片问题了,实现简单,运行高效。

但同时,他的缺点也显而易见,我好好的一块8g内存被你用成了4g,这代价未免太大了点!

研表究明,新生代的对象犹如蜉蝣(并不是所有的,研表究明大概98%),朝生夕死。打个比方,我有两个围栏,一个围栏养了100头猪,一天下来活了两只,然后我把这两只放在另一个围栏里面,并在这个围栏里面补了98头猪,一天下来活了4只,既然存活率这么低,那么我为什么还要分配这么大一块地来放存活的猪呢,我是不是可以建一个小围栏用来放活下来的猪呢?本着这样的想法,我将原来的围栏拆了,建了一大一小两个围栏,大的围栏养猪,小的围栏用来存放每天活下来的猪,大的围栏一天放200头猪(别杠分成一大一小不能放200头猪,只是打比方),一天下来就能活4只,这样效率是不是一下就提高了。但是活下来的猪也可能会死,这样就再建一个小围栏,当一个小围栏放不下的时候,就将小围栏和大围栏里面存活的猪统一移到另一个小围栏里面,(如果正在使用的小围栏里面的猪一只都没有死,而大围栏已经满了,此时我的另一个小围栏由于大小和已使用的围栏大小一致,因此肯定是装不下的,那我的猪该往哪放呢?这个时候我突然想起来我还有一个老的围栏(老年代,别问哪来的,问就是我有),这个时候就可以通过老围栏(老年代)进行分配担保了。),并且将之前满的大围栏和小围栏清空,如此循环往复。

以上内容书上的话就是:将内存分为一块较大的Eden空间,和两块较小的Survivor空间,每次使用Eden空间和其中一块Survivor空间,当回收时,将Eden空间和Survivor空间里面存活的对象一次性地复制到另一块Survivor空间上,最后清理掉Eden和刚才使用过的Survior空间。

在HotSpot虚拟机中,新生代默认的Eden区和Survior区的内存大小比例是8:1:1,也就是说,每次使用的内存占总内存的90%,相比之前的50%可好太多啦!

 

三、标记-整理算法

复制收集算法在对象存活率较高时就要执行较多的复制操作,效率将会降低。

现在就来讨论下极端情况。

当被使用的内存里面的对象100%存活时,如果不想使用五五开的复制收集算法,就必须要有一个额外的内存空间为其分配担保,在新生代内存中,分配担保的是老年代,而老年代没有为其分配担保的额外内存空间,因此,在老年代内存里面不能使用复制收集算法,根据老年代GC不频繁,相对稳定;每次清理内存,清理的比较少的特点,有人提出了“标记-整理算法”,标记过程和标记-清除算法一样,但是后续步骤不是对所有可回收对象进行清除,而是让所有存活对象向一端移动,然后清理掉端边界以外的内存。

四、分代收集算法

分代收集算法并没有什么新的思想,只是根据对象的存活周期不同,将内存划分为几块。一般是将java堆分为新生代老年代,这样就可以根据各个年代的特点采用适当的收集算法,比如上面提到的,新生代新生对象多,存活率低,且有老年代为他进行分配担保适合使用复制收集算法;而老年代对象存活率高,且没有额外空间进行分,就必须使用标记-整理算法或者标记-清除算法。

 

参考书籍:《深入理解java虚拟机》周志明 著

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值