Java虚拟机(JVM)的垃圾回收机制(GC)详解(上)

如何判断垃圾?

简单来说我们不用了,但是还占用着内存空间就是垃圾。我们需要一种方法判断哪些是我们不会在用的对象,目前有以下几种主流的方法:

  • 引用计数法
    对每个对象都保存一个计数器,当对象被引用时,计数器就加一,引用失效计数器就减一。当计数器为零时,就代表了此对象可以回收了。但是,此方法存在的一个问题就是,当对象间循环引用时就无法被垃圾回收器回收。
  • 可达性分析法
    在这里插入图片描述

从GC Roots进行遍历,如果不可达,就视为可以回收。那么哪些对象可以作为GC Roots呢?在java语言中主要有以下几种:

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

如何收集垃圾?

接下来我们将介绍几种收集垃圾的算法:

  • 标记-清除算法:
    这个算法很简单,就是先把垃圾标记出来,然后清楚。
    优点: 简单
    缺点: 时间上,标记和清除效率都不高,空间上,碎片比较多可用空间不连续。
  • 复制算法:
    这个算法也不难,就是把可用内存分成两块,当一块用完了,就把“活着”的对象复制到另一块,当前块的空间就可以完全清理了。
    优点: 无碎片
    缺点: 空间代价大内存少了一半,复制效率低。
  • 标记-整理算法:
    此方法标记和 标记-清除 算法一样,整理主要是将活着的对象都移动到一边。
    优点: 没有内存碎片
    缺点: 整理效率低
  • 分代收集算法:
    刚刚介绍了几种算法,都有自己的优缺点,分代收集就是发挥他们各自的长处。例如,存活对象多就用标记-清除算法,存活的少就可以用复制算法

JVM 的具体实现

以上讲的都是理论层面的分析,接下来我们要说的就JVM的具体实现。(我们主要讨论的是HotSpot虚拟机的实现)

  • 优化枚举GC Roots
    JVM 用OopMap的数据结构保存了哪些地方存放着对象引用,以提高枚举的效率。

  • 安全点
    我们先来理解一下这个名词,首先,我们刚才提到了OopMap数据结构存放着对象的引用,但是程序是一直在执行的,我们每执行一条语OopMap就会发生变化(因为可能有对象的产生和新的引用建立),显然我们不能没执行一条语句就生产一遍OopMap,因此安全点的概念就被引入了,只有程序执行到安全点时才会生成一遍OopMap。
    这其实又引入了一个其他的问题,当我们要进行GC时有的线程没有到安全点怎么办呢?有两种中断可以保证每个线程执行到安全点。一种是抢先式中断、一种是主动式中断。抢先式中断是指将先将所有线程中断,再使没有到安全点的线程跑到安全点。主动式中断,是要设置一个标志,线程主动的去轮训,中断标志位真就中断挂起。

  • 安全区域
    安全区域就是对安全点的一个扩展,如果线程还没运行到安全点,又没有抢到CPU,不能跑到安全点,那就比较尴尬了,所以有了安全区域的概念,进入安全区域就自己标记一下,离开前判断一下需不需要进行根节点的枚举,如果需要且没完成,就不能离开。

具体的垃圾回收器

在这里插入图片描述

上图是我们将要介绍的所有垃圾回收器(就这配色,不配获得一个赞么?),大家先看一下,我会在下一篇博客中一一介绍。不然,太长大家就不想看了(已经23:28分了,想下班了:))

我来兑现承诺了!!!
Java虚拟机(JVM)的垃圾回收机制(GC)详解(下)—— 垃圾收集器

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

从前慢慢慢死了

打钱!一分也行啊!!!

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

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

打赏作者

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

抵扣说明:

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

余额充值