Java 虚拟机基础知识(二)

Java 虚拟机基础知识(二)

该文章首发于微信公众号“字节流动”

JVM 垃圾回收机制

理解 JVM 垃圾回收机制需要弄清楚两个问题:

  • 什么是垃圾,或者怎么判定垃圾?
  • 怎么回收,或者通过什么方式回收垃圾?

什么是垃圾,或者怎么判定垃圾?

“垃圾”即不再存活的对象,判定对象是否存活,一般有两种方法:

  • 引用计数算法
  • 可达性分析算法

引用计数算法

为每一个创建的对象分配一个引用计数器,用来存储该对象被引用的个数。当有一个地方引用它,引用计数器就加 1 ;当引用失效,引用计数器就减 1 ;当引用计数器为 0 ,意味这个对象没有被使用,可以认为“对象死去”。

但是,引用计数算法很难检测出对象之间的循环引用,当两个对象互相引用,即时它俩都不被外界任何东西引用,它俩的计数都不为零,因此永远不会被回收。所以, JVM 并没有用此方案来检测对象是否存活。

可达性分析算法

可达性分析算法的基本思路是以一系列 GC Roots 对象为起点出发,然后向下搜索,搜索所走过的路经称为引用链,处在引用链上的对象称为可达对象,或存活对象;而当一个对象到 GC Roots 对象没有任何引用链相连,则被视为不可达对象,或垃圾。JVM 采用可达性分析算法判断对象是否存活。
在这里插入图片描述
JVM 中哪些对象可以作为 GC Roots?GC Roots 对象本身一定是可达的,这样从它们出发遍历到的对象才能保证一定可达。一般有如下几种:

  • 虚拟机栈(帧栈中的本地变量表)中引用的对象。
  • 方法区中静态属性引用的对象。
  • 方法区中常量引用的对象。
  • 本地方法栈中 JNI 引用的对象。

通过什么方式回收垃圾?

常用的垃圾回收方式有:

  • 标记-清除算法 (Mark-Sweep)
  • 标记-整理算法 (Mark-Compact)
  • 复制算法 (Copying)
  • 分代收集算法 (Generational Collection)

标记-清除算法 (Mark-Sweep)

基本原理:先标记出需要回收的对象,然后一并回收被标记过的对象。

通过可达性分析算法判定对象不可用,是标记的第一步,如果对象已经被标记一次,它将被进行一次筛选,筛选条件为对象是否重写了 finalize() 方法,或者 finalize() 已经被虚拟机调用。当对象没重写或 finalize() 已经被执行过,就证明对象已经没有可能再回到可用状态,待虚拟机第二次标记它时,就会被放到回收的集合中。

标记-清除算法缺点:

  • 效率低,标记和清除两个过程的效率都不高
  • 易产生内存碎片,标记清除之后会导致内存中出现大量的不连续的内存碎片,之后分配较大对象的内存空间时,导致没有足够的连续内存,可能会触发另一次的垃圾回收,这个问题也间接的反映出了效率不高。
    当然, JVM 并不是只用这一个算法去回收垃圾,而是在对象存活率较高的时候,使用这个算法。

标记-整理算法 (Mark-Compact)

标记-整理算法可以说是标记-清除算法的完善版,标记-清除算法容易产生内存碎片。标记-整理算法是在标记后,将所有存活的对象都向一端移动,然后再清理掉边界以外的内存。

复制算法 (Copying)

复制算法的基本思想是将可用内存容量划分为大小相等的两块,每次只用其中的一块,当这块内存用完了,就将还存活的对象复制到另一块上,然后清除已使用的那块。这样每次固定回收一半内存,实现简单,运行高效,并且不会出现内存碎片。这个算法的代价也很大,就是要牺牲一半的内存。
主流的商业虚拟机一般采用复制算法来回收新生代,因为新生代里的对象 98% 都是“朝生夕死”,所以并不需要按照 1:1 的比例划分内存空间。一般新生代只有 10% (不绝对)左右的对象存活,虚拟机的划分比例往往高于 8:1 。

分代收集算法 (Generational Collection)

目前主流的商业虚拟机均采用分代收集算法,根据对象存活周期的不同将内存划分为几块,一般分为新生代和老年代。

  • 新生代:对象存活率低,每次垃圾回收后都只有少量对象存活,因此适合用复制算法。
  • 老年代:对象存活率高,适合使用标记-清除或者标记-整理算法。

联系与交流

微信公众号
我的公众号
个人微信
我的微信

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

字节流动

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值