美文网首页程序员
JVM-垃圾回收算法

JVM-垃圾回收算法

作者: 我可能是个假开发 | 来源:发表于2023-02-04 17:41 被阅读0次

    一、引用计数法

    1.原理

    统计每一个对象被引用的次数,如果引用次数为0就释放对象。能立即回收无用内存。

    2.实现

    当一个对象要重新赋值引用时:

    • 把新对象引用计数+1
    • 老对象引用计数-1
    • 赋值

    伪代码:


    image.png

    3.存在的问题

    • 并发场景下,对引用计数的修改需要和对象指针的修改保证同步,往往需要加锁或者复杂的无锁算法
    • 有时会引发连锁式的回收
    • 无法有效解决循环引用
    循环引用.png

    注意:要先加,再减,否则如果刚好减到0的话就会被回收了。

    二、复制算法

    复制算法.png

    1.原理

    把程序运行的堆分成大小相同的两半,一半为from空间,一半为to空间。利用from空间进行分配,当空间不足以分配对象的时候,触发GC。GC会把存活的对象全部复制到to空间。复制完成以后,会把from和to互换。

    2.特点

    • 1.分配采用bump the pointer,每次都把top指针向后移动即可。复制的存活对象多大,指针就移动多大。
    • 2.回收是否高效取决于存活对象的比例。存活对象越少,效率越高
    • 3.无内存碎片
    • 4.需要浪费一半内存空间
    • 5.需要停顿
    • 6.实现简单

    在整理的过程 需要停顿业务线程,因为在整理对象的过程,指针会发生改变。

    3.对象位置发生变化,指向的引用维护方法

    1⃣️引入中间层

    引入间接指针.png

    虽然在复制的过程中变得简单,但是中间层的分配和回收并不容易做;而且每次访问对象属性都变成了再次访问,性能的退化也是不能接受的。

    2⃣️使用forwarding指针

    使用forwarding指针.png

    1.A复制到to空间
    2.因为A指向着C,所以C也直接复制到to空间,修改C的引用,让A指向C'
    3.B复制到to空间,但是B的指针还是指向的from空间的C;
    4.在第二步C复制到to空间时,让C指向新的C'地址(forwarding指针)。
    5.B从C中的对象头中拿到forwarding,指向新的C'。

    4.提高空间利用率

    将Eden空间分配成Eden,Survivor0和Survivor1区域。这样Survivor空间的浪费就可以减少了。
    配置Survivor空间大小是JVM GC调参中的重要参数。
    例如 -XX:SurvivorRatio=8 代表Eden:S0:S1=8:1:1

    提高空间利用率.png

    from:S1+Eden
    to:S0
    第一次:把s1+Eden一起经过回收存活的放入S1;

    from:S0+Eden
    to:S1
    第二次:把S0+Eden一起经过回收存活的放入S0;

    浪费的空间就只有S0或者S1的大小。

    三、标记清除法

    标记清除法.png

    1.原理

    使用链表管理所有的空闲区域。在Mark阶段(标在对象头),将所有的存活对象识别出来,将不存活的对象所占用的内存还给链表。

    2.特点

    • 1.分配和回收都要操作链表
      分配要查询链表哪个位置可以放得下这个对象,回收再将内存还给链表
    • 2.有内存碎片
    • 3.总体的内存空间利用率较高
    • 4.可以用很小的代价实现并发标记和清除(在标记的过程中对象指针不会发生变化,不需要停止业务线程)

    极客时间《Java面试冲刺班之JVM难点攻克》学习笔记Day21

    相关文章

      网友评论

        本文标题:JVM-垃圾回收算法

        本文链接:https://www.haomeiwen.com/subject/nnuohdtx.html