内存回收算法

判断对象是否需要回收

引用计数算法

判断对象是否被其他对象所引用,当对象未被引用时,可被回收
实现方式:给对象添加一个引用计数器,当有地方引用时计数器就加1
相互循环引用

可达性分析算法

从根节点开始,判断对象是否可达,若不可达,则被判定为可回收对象

引用

有一类对象在堆内存充足时继续留在内存中,当堆内存不够时进行GC回收

  • 强引用:强应用在GC时永远不会被回收
  • 软引用:有用但是非必须的对象。在发生内存溢出前会将内存标记进行二次回收。若回收完还是内存不够则outofmemory
  • 弱引用:弱引用用来描述非必要对象。即需要回收对象,若引用在下一次GC时会被回收
  • 虚引用:

回收方法区

方法区的回收主要对废弃常量和无用类进行回收。
废弃常量:当前系统中没有任何一个同名且类型系统的常量
无用类:1、所有实例都被回收2、父加载器被回收3、对象未被引用4、无反射访问该类的方法

内存回收算法

标记清除

标记所有需要回收的对象,然后清除
不足:

  • 效率不高
  • 会产生不连续的内存碎片

标记整理

复制收集算法针对内存存活率高,一直存活的对象来说,频繁复制会降低效率。针对老年代,更适合标记整理算法
先标记需要回收的对象,然后将标记后的对象整理成连续的对象,将不需要的对象清除

复制算法

将内存划分为两块内存一样的内存,每次使用其中一块,当内存使用完时,将活着的对象复制到另一块,然后将使用过得内存一次性清理。

将内存划分为两块内存一样的内存 每次使用其中一块
当内存使用完时 将活着的对象复制到另一块
将使用过得内存一次性清理
商业虚拟机内存回收
  • 将内存中划分为Eden空间和两块较小的survivor空间,每次使用Eden和其中一块survivor。当回收时,将Eden和survivor空间中的对象一次性复制到另一块survivor,最后清理Eden空间和survivor空间
  • Hotspot虚拟机Eden和survivor空间内存比例为8:1,当复制的时候survivor空降内存不够时,将会触发分配担保
  • **分配担保:**如果一块survivor空降中内存不够时,复制的对象将会通过分配担保机制将对象放入老年代。

分代算法

将java堆分为年轻代和老年代。年轻代采用复制清除算法,老年代使用复制整理算法或者标记清除算法

Hotspot垃圾回收算法实现

枚举根节点

  • 可作为根节点的对:虚拟机栈中引用的对象、方法区中常量引用的对象、方法区中常量引用的对象、本地方法栈中引用的对象
  • 通过可达性分析从GC ROOT中找引用的对象,可达性分析执行过程中需要停顿所有java线程

安全点

  • 通过可达性分析和oopmap快速标记需要回收的对象
  • 任何一条语句的执行并不会生成oopmap,在特定的位置记录信息,这些位置称为安全点
  • 安全点的选定以程序是否具有让程序长时间执行的特性。长时间执行的最明显特征就是指令序列复用,例如:循环跳转、方法调用、异常跳转等,会产生安全点。
    如何在GC时让所有线程跑到安全点附近:抢先中断和主动中断
  • 抢先中断:不需要线程的执行代码主动配合,发生GC时,把所有线程全部中断,如果有线程不在安全点时,则恢复线程,让线程跑到安全点上,目前没有虚拟机采用这种方式
  • 主动中断:不需要对线程进行操作,需要GC时设置一个标志,线程轮询,发现标记为真时主动挂起。

安全区域

为解决部分线程已经被挂起,无法进入安全点,通过安全区域解决
安全区域为一段代码中引用关系不会发生变化,在这个区域任何位置开始GC都是安全的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值