JVM GC简介

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_39161031/article/details/82810230

GC垃圾回收

    本章节主要针对于以下三个问题的两个问题进行描述。

如何判定为垃圾对象?

  • 引用计数法

        在对象中添加一个引用计数器,当有地方引用这个对象的时候这个引用计数器的值就+1,当引用计数器失效的时候,计数器的值就-1。当引用计数器为0就判断为垃圾对象。
        图解(灵魂画手又重出江湖啦哈哈哈哈哈哈哈哈):

        假设栈中有一个指向(直接引用或者句柄的方式)堆中的对象,如果我们把引用置为null,那么引用计数器就会-1.当垃圾回收器发现引用计数器为0就会进行回收。
        缺点:如果对象之间属性相互引用,栈中就没有引用指向它们,但是它们的引用计数器不为0,并不会回收这些对象。这种算法现在基本不用。。

  • 可达性分析
        通过GC Root往下走,往下走的过程叫做引用链。当一个对象对GC Root节点没有任何引用链连接的时候,这个对象就可以被回收了。
        那,哪些对象可以作为GC Root嘞?

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

如何回收?

  1. 回收的策略
        标记清除算法
        用引用计数法或可达性分析法标记出来需要回收的对象,然后再进行清除
        缺点:效率不高。内存空间不连续。如果有一个比较大的对象要分配内存就很有可能没有连续的内存给它分配。
        复制算法
        在熟悉复制算法之前,先重新理一下堆。堆可以分为新生代老年代。新生代又可以分为Eden(伊甸园,只要有新的对象创建就会丢到伊甸园)、Survivor、Tenured Gen。
    在这里插入图片描述
        复制算法把堆中的内存分为两个部分,只用一部分。当gc的时候,将存活的对象复制到另外一半区域中,排练好。再进行回收,就能得到连续的内存空间。
        缺点:只用一半会造成内存的浪费。针对内存浪费现在又有了新的方法,如下图:
    在这里插入图片描述
    一般在新生代中对象的存活率为10%,超过10%对象存活就要内存分配担保机制从老年代中获取内存。所以这个算法针对新生代会比较高效。
        标记整理算法
        如果对象存活率较高,复制算法的复制过程就比较耗费性能。标记整理算法就是在标记算法的基础上的升级,在标记完需要回收的对象后,将存活的对象向一端移动,再直接清理掉边界以外的内存。
        分代收集算法
        根据内存的分代选择不同的垃圾回收算法,针对新生代选择复制算法,针对老年代选择标记整理算法。
  2. 常见的垃圾回收器 (有空整理各自优缺点、算法)
    Serial
    ParNew
    Parallel Scavenge
    CMS
    G1

何时回收

猜你喜欢

转载自blog.csdn.net/weixin_39161031/article/details/82810230