Java虚拟机JVM垃圾回收算法

1 篇文章 0 订阅

为什么需要垃圾回收

假设一个对象创建的意义就是进堆被执行,那如何保证堆的空间是足够的?假设不够又该执行什么方法?那么在这里看垃圾回收机制就是保证内存剩余空间足够(当然好处远不于此)

垃圾回收GC各类算法

引用计数器法(java1后移除)

这个方法会让每个对象都含有一个计数器,当对象被引用计数器就会+1(到达15时对象进入old区),当对象的引用离开作用域则被减一,这里可以看成引用被销毁,最低为0,当计数器到0时对象会被回收。

这个方法很简单,但是弊端不少,要看计数器是否为0要判断所有对象的引用计数器,假设一下,如果一个对象存在于组合类中被循环调用呢?若没有合理的代码规范,计数器会不停的+1-1,若回收扫描时为0但下一刻就为1该怎么办?所以这种计数器方法很少被实现

GC Roots可达性分析法(根搜索)

首先要判定一些GC Roots对象作为最上层的根

判定GC Roots的条件有很多因素:局部变量表中的变量:栈帧中局部变量表变量能够找到跟其间接,直接使用它的引用。static成员,类加载器,thread,活跃线程的引用对象。

这个方法通过设定一系列符合条件的根,起点来连接各个方法中的引用来确定需要回收的对象。跟GC Roots对象之间存在相互调用,被使用,跟现有活跃线程的引用相互关联,都会加上一层关系(当然不止这些还有靠其他算法实现的)。通常这个方法的结构都是想象成一个树形或者直线向下的结构,但是想象成这类结构时碰上很多复杂的组合时或者调用其他引用,引用之间又跟其他引用有更多的联系时,这种结构不免会觉得很复杂。所以我更喜欢把可达性分析法想象成一张不停在堆内存中过滤对象的“网”,这张网会捞起符合回收条件的对象,而跟其有关联的对象又跟其存在联系也会被捞起,而不需要被回收的对象在则不会沾上这张网,继续留在内存中。

这个方法非常灵活准确的判断哪些该回收哪些不该回收,相比引用计数器法能更精准的判定对象是否该回收,但注意不是所有的运行时数据区都适合使用这种判断。

标记清除:

 

运行大致如下,先标记出哪些对象需要回收,然后清理之前所有标记的对象。这是最基本的算法,缺点也比较明显:标记需要扫描整个堆内存空间,比较耗时,且清理对象后会产生空间碎片的问题。所以多是old代中使用

复制算法:

效率较高,其核心是划分出两块内存区域,通常划分的大小为5:5,两者交替使用。

使用时优先往其中一块区域填充对象,当其中一块区域趋近满溢时,新加入的对象就会直接进入另一个区域并触发gc,此时就会将之前区域所有还"活"者的对象复制到当前区域并交换角色,复制交换完成之后清除上一块区域 的所有对象。这种方法效率非常高,但也非常浪费内存资源,空闲一半内存这种方法放在对象生命周期都较长的old区中显然不行,所以多半用在对象更新频繁生命周期较短的新生代中。

标记整理

其运行步骤和上面标记清除大致一样,不过最后会对所有的内存区域进行整理,使其整齐排列,所以解决了空间碎片的问题。

 

以上内容只是本人的理解,欢迎各位同学补充指正。3Q

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值