JVM垃圾回收机制学习

一、可回收对象判定方法

识别方式有两种。一是,引用计数算法;二是,可达性分析。

第一种方法:引用计数算法。当一个对象被引用时,引用计数器加1,当引用失效时,引用计数器减1。当一个对象的引用次数为0时,表示这个对象是可以被回收的。这种方法的优点是快和简单,只要将所有对象遍历一遍便可,缺点是:如果对象之间存在循环引用,则无法回收。比如:对象A引用了B,B中也引用了A,如果除此之外没有任何对象引用了A和B,很显然AB是应该被回收的,但是此时两者的引用次数是1,这时,JVM无法对AB进行回收。

第二种方法:可达性分析。通过一系列被称为“gc roots”的对象作为起点,从这些节点开始向下进行搜索,搜索所走过的路径成为引用链。当一个对象到“gc roots”之间没有任何引用链相连时,则该对象是不可达的,也就是可以回收的。这种方式可以解决循环调用的问题,JVM中使用的是这种判定方法。

二、垃圾回收算法

垃圾回收算法有以下四种:

标记-清除算法;
复制算法;
标记-整理算法;
分代收集算法;

标记-清除算法分为“标记”和“清除”两个阶段,“标记”阶段将需要回收的对象标记出来,“清除”阶段回收被标记的对象。这是一种最基本的垃圾回收算法,后面很多种垃圾回收算法都是基于这种算法的不足改进而得到的。这种回收方法的缺点是回收之后会产生大量内存碎片,因为回收过程只是简单的释放掉被标记对象。内存碎片太多的话,当我们需要分配大内存对象时,无法找到连续的内存空间,以致分配内存失败。

复制算法将内存分成两半,一半使用(在用内存),一半不用(未用内存)。标记过程同上,只是在回收时,把在用内存中的未标记对象复制到未用内存中,然后把在用内存统一全部回收。这种方法不会产生内存碎片,但是相当于把内存容量减少了一半。在实际算法中,在用内存和未用内存往往不是对半分的,因为如果每次清理的时候,大部分对象都死了,只有少部分存活(实际上,下面的分代收集算法中的新生代就符合这样的特点),那么,未用内存只要很小就可以了。

标记-整理算法也是由标记-清除算法发展而来,只是“清除”之后,会把内存整理一遍,这样就没有碎片了。但是,这种算法要考虑一致性问题,就是整理的过程中,标记不能变动,这就相当于虚拟机要暂停,等待内存整理完毕再运行,而整理过程还是挺耗时的。但是,如果对象存活的时间很长,存活率很高,每次清理都只有少部分对象死亡(实际上,下面的分代收集算法中的老生代就符合这样的特点),那么,这种算法消耗的时间会大大减少。

分代收集算法,这是听得最多的一种算法了,就是将对象分为新生代和老生代,新生代对象的特点是存活时间短,存活率低,老生代刚好相反。根据新生代和老生代的特点,对新生代使用复制算法,对老生代使用标记整理算法。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值