• java垃圾回收机制


    大纲:

    1. 虚拟机内存模型
    2. 判断对象已死
    3. 四种引用
    4. 垃圾回收算法
    5. 垃圾回收策略
    6. 垃圾回收器

    一、虚拟机内存模型

    根据 JVM 规范,JVM 运行时区域大致分为 方法区、堆、虚拟机栈、本地方法栈、程序计数器 五个部分。

    二、判断对象已死

    1. 引用计数算法:为每个对象增加一个计数器,被引用一次+1,引用失效-1,引用数==0则回收。优点:简单,高效。缺点:如果2个对象除了相互引用外无其他引用,则无法回收。
    2. 可达性分析算法:一个对象通过一条引用链能达到gc roots则判定对象有效,否则会被回收。gc roots包括虚拟机栈中引用对象、方法区中类静态属性引用对象、方法区中常量引用的对象、native方法引用的对象。

    三、四种引用

    1. StrongReference-强引用:Object o = new Object();gc不回收,内存满则抛出OutOfMemoryError。
    2. SoftReference-软引用:gc会在内存不足时回收,可以和ReferenceQueue联合使用,软引用引用对象被回收,虚拟机会把这个软引加到相关引用队列中。
    3. WeakReference-弱引用:gc只要发现弱引用的对象就回收,可以和ReferenceQueue联合使用,弱引用引用对象被回收,虚拟机会把这个弱引加到相关引用队列中。
    4. PhantomReference-虚引用 被虚引用引用的对象就和没有引用一样,虚引用必须和ReferenceQueue联合使用,gc回收前,发现对象被虚引用引用,就在回收前把虚引用加到相关队列中。

    四、垃圾回收算法

    1. 标记清除-将垃圾标记后清除,但会造成内存碎片化
    2. 标记整理-将存活对象移动到一端,清除其他内存,解决了内存碎片化问题,但由于频繁移动内存导致效率低。
    3. 复制-将内存一分为二,每次使用一半,清理时将存活对象复制到另外一半,然后清理当前一半,但每次只能使用一半内存。
    4. 分代垃圾回收-虚拟机将堆分为老年代和年轻代,年轻代朝生夕死适合复制算法,老年代存活率高,适合标记清除、标记整理算法。

    五、垃圾回收策略

     堆内存是虚拟机中主要管理区域,占用内存最大。

    Java 堆主要分为2个区域-年轻代与老年代,其中年轻代又分 Eden 区和 Survivor 区,其中 Survivor 区又分 From 和 To 2个区。

    Eden-由于98%的对象是朝生夕死,eden在年轻代占据大一些,大多数对象出生在eden区。每次eden满触发minor gc。

    Survivor-from,to两块作用相同,当发生minor gc,eden和(from/to)中存活的对象被复制到(to/from)中。

    Old-老年代占据着2/3的堆内存空间,major gc和full gc 的时候才会进行清理。老年代中包括:

    1. 大对象:避免在Survivor中来回复制,避免Survivor装不下。
    2. 长期存活对象:对象每次经历minor gc年龄+1,16岁后进入老年代。
    3. 动态对象年龄判定:虚拟机并不是永远地要求对象的年龄必须达到了MaxTenuringThreshold才能晋升老年代,如果在Survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代,无须等到MaxTenuringThreshold中要求的年龄。对应虚拟机参数-XX:TargetSurvivorRatio 目标存活率,默认为50%

    六、垃圾回收器

    下图为垃圾回收器的常见组合,垃圾回收器分新生代回收器,老年代回收器,全年代回收器(G1)

    1.Serial:单线程,每次回收STW

    2.ParNew:Serial多线程版本

    3.Parallel Scavenge:可以控制吞吐量(工作时间/工作时间+gc时间),默认使用GC自使用策略(动态调整新生代各部分大小),也可以调整两个参数:

    • XX:MaxGCPauseMillis 控制最大的垃圾收集停顿时间
    • XX:GCRatio 直接设置吞吐量的大小

    4.Serial Old:Serial老年代版本

    5.Parallel Old:ps老年代版本

    6.cms:停顿时间短,注重服务端响应速度

      cms垃圾回收有4个阶段,采用三色标记的方法进行标记(黑色:本身及子结点全部被垃圾回收器访问过;灰色:本身被访问,子结点未被全部访问;白色:未被访问过)

        1.初始标记:stw,对象初始为白色,gcroots为黑色,将gcroots直接引用的对象标记灰色

        2.并发标记:根据可达性分析,在用户线程不停止的情况下,扫描灰色及其子结点;同时并发标记期间黑色结点新增的引用关系会被记录下来,因为会出现引用消失问题(某个白色结点本来被灰色结点引用,突然这个引用消失,但被黑色结点重新引用,由于黑色            结点不被再次扫描,所以在并发标记后该对象还是白色)

        3.重新标记:stw,扫描并发标记阶段黑色结点新增的引用关系,解决对象消失问题

        4.并发清除:并发清除白色标记的对象

      cms缺点:

        1.并发标记和并发清除占用cpu

        2.由于并发,无法清除浮动垃圾,当浮动垃圾产生的速度大于并发清除速度,老年代的空间被占用到一定比例时,需要Serial Old来帮忙进行依次major gc

        3.采用标记清除算法,产生内存碎片,碎片严重时,需要Serial Old来帮忙进行依次major gc

    7.g1:全年代的垃圾回收器,注重服务端响应速度

      g1特点:

        1.将堆内存默认分为2048个等大的Region,每个Region可以是年轻代,也可以是老年代,还有可能时大对象,每代不再时一个连续的区域。每个Region有自己的回收价值(垃圾对象比例,预期回收时间与效果)

        2.可以设置停顿时间,控制每次垃圾回收的总时长

        3.回收时,筛选价值高的Region来回收,由于有停顿时间限制,可分多次回收

        4.靠新生代、老年代达到Region的比例来判断是否需要进行回收

        5.标记过程与cms一样采用三色标记

  • 相关阅读:
    RFID亮灯电子标签在仓储管理中的应用
    漫画:寻找股票买入卖出的最佳时机(动态规划)
    JAVA深入解析-36个话题-Two
    一行代码让训练速度提升2倍,飞桨自动混合精度技术详解
    追源码的平凡之路
    看完这篇,你也是字符编码大神!
    微服务的熔断原理与实现
    经典论文复现 | PyraNet:基于特征金字塔网络的人体姿态估计
    一文看懂人机对话
    「Spring Boot 2.4 新特性」一键构建Docker镜像
  • 原文地址:https://www.cnblogs.com/liuboyuan/p/10551756.html
Copyright © 2020-2023  润新知