JVM垃圾回收算法实现

╰+攻爆jí腚メ 2021-11-11 07:24 357阅读 0赞

在JVM对垃圾进行回收的时候,需要对对象进行判断是否还“存活”,因为进行回收的时候需要保证在一致性的快照上进行,需要停顿下来进行垃圾回收。

1.如果对逐渐检查这里边的引用的话,那么必然会消耗大量的时间,怎么去减少这个时间呢?

目前大部分java虚拟机使用的是准确式GC,这样当执行系统停顿下来,并不需要一个不漏地检查完有执行上下文和全局的引用位置。在HotSpot虚拟机中,是使用一种OopMap的数据结构来达到这个目的(从外部记录下来类型信息,存成映射表),在类加载的时候,HotSpot就把对象内什么偏移量上是什么类型的数据计算出来,在JIT编译的时候也会在特定的位置记录下栈和寄存器中那些位置是可用的。这样GC扫描的时候就可以直接得知这些信息了。

2.那么线程应该停在哪里呢?

OopMap内容变化的指令非常多,如果为每一条指令都生成对应的的OopMap(即在每个时间点都做映射),这样的消耗是非常大的。

所以HotSpot也没有这样做,只是在特定的位置做了映射,这些位置称为安全点。程序需要暂停在安全点。

3.安全点应该怎么设置?

安全点太多GC会太频繁,安全点太少又会导致GC等待时间太长。

安全点一般设置位置:

  • 循环的末尾
  • 函数返回之前
  • 调用方法之后
  • 抛出异常的位置

4.怎么让所有线程暂停在安全点上?

1:抢先式中断:

  1. GC发生时,中断所有线程,判断线程是不是停在了安全点,如果不是则恢复线程,让他跑到安全点再暂停。但是现在几乎没有虚拟机实现采用抢先式中断来暂停线程从而响应GC事件了。

2:主动式中断:

  1. 主动式中断不直接对线程进行操作,仅仅设置一个标志,各个线程执行时主动去轮询这个标志,如果标志为真的话,那么开始中断线程。轮询的标志和安全点是重合的。

5.对于”不执行的程序“如何进行垃圾回收?

”不执行的程序“:指线程处于Sleep或者Blocked状态,这时候无法影响JVM的中断请求。

这个时候需要用安全区来解决。

安全区域是指在一段代码片段之中,引用关系不会发生变化,在这个区域任何地方开启GC都是安全的。

当线程执行到安全区的代码时,首先标识自己已经进入了安全区,当这段时间里jvm要发起GC时就不用管标识自己为安全区状态的线程了,当线程要离开,要检查系统是否已经完成了GC,如果完成了线程继续执行,否则他需要等待收到可以安全离开的信号为止。

发表评论

表情:
评论列表 (有 0 条评论,357人围观)

还没有评论,来说两句吧...

相关阅读

    相关 JVM垃圾回收算法

    > 全文是在阅读了《深入理解Java虚拟机》进行的摘录笔记 标记-清除算法 算法分为“标记”和“清除”两个阶段:标记出所有需要回收的对象,在标记完成后,统一回收掉所有被

    相关 JVM垃圾回收算法

    Java是一门不用程序员手动管理内存的语言,全靠JVM自动管理内存,既然是自动管理,那必然有一个垃圾内存的回收机制或者回收算法。 在Java堆上分配一个内存给实例对象时,此时

    相关 JVM 垃圾回收算法

    在说垃圾回收算法之前,先谈谈JVM怎样确定哪些对象是“垃圾”。 1.引用计数器算法: 引用计数器算法是给每个对象设置一个计数器,当有地方引用这个对象的时候,计数器\+1

    相关 JVM垃圾回收算法

    前言 程序计数器,虚拟机栈,本地方法3个区域随线程而生,随线程而灭,栈中的栈帧随着方法的进入和退出有条不紊地执行着出栈和入栈操作,每一个栈帧中分配多少内存,基本上是在类结

    相关 JVM垃圾回收算法实现

    在JVM对垃圾进行回收的时候,需要对对象进行判断是否还“存活”,因为进行回收的时候需要保证在一致性的快照上进行,需要停顿下来进行垃圾回收。 1.如果对逐渐检查这里边的引用的话