• GC垃圾收集器和收集算法及JVM调优


    在这里插入图片描述

    Garbage Collection 垃圾回收机制(英文简写GC):当需要分配的内存空间不再使用的时候或者空间不足时,JVM将调用垃圾回收机制来回收内存空间

    • 新生代和老年代在中的占比
      新生代 1/3
      老年代 2/3
      • 新生代中伊甸园和幸存者占比
        Eden 8/10
        S0 1/10
        S1 1/10

    各GC回收范围
    回收算法
    GC 回收器
    JVM常用指令
    JVM常用工具

    各GC回收范围

    • 部分收集(Partial GC) : 指不是完整收集整个Java堆的垃圾收集, 其中又分为:
      • 新生代收集(Minor GC): 新生代的垃圾收集.
      • 老年代收集(Major GC): 老年代的垃圾收集 , 目前只有CMS收集器会有单独收集老年代的行为.
      • 混合收集(Mixed GC): 整个新生代以及部分老年代的垃圾收集. 目前只有G1收集器会有这种行为
    • 整堆收集(Full GC) : 收集整个Java堆和方法区的垃圾收集

    在这里插入图片描述
    当eden区域满了,将会执行 Minor GC,将大部分回收,剩余的对象将放入S0区域.在执行Minor GC时,会触发STW


    在这里插入图片描述
    当再次进行Minor GC时,除了将eden的对象放入到S1区域外,同时将S0区域内的对象也移到S1区域,并将值+1
    S0或S1其中之一将始终保持为空


    在这里插入图片描述
    当S0/S1区域内的对象经过多次Minor GC回收后依旧存在并阀值达到15(默认)时,将移动动到老年代


    在这里插入图片描述
    当老年代空间不足时,将会尝试触发Minor GC ; 如果空间还是不足,则触发CMS 垃圾收集器 (Major GC) ; 如果Major GC后内存仍然不足,则报错OOM (OutOfMemoryError) ; Major GC速度要比Minor GC慢10倍以上
    Najor GC 同样会执行STW


    在这里插入图片描述
    经过多次Major GC后的对象仍未被回收,将移到元空间


    回收算法

    • 标记 - 清除算法
      分为"标记"和"清除"两个阶段,在经过GC Root引用链后,可以将需要可回收的进行标记,然后再进行清除;或者将存活的对象进行标记,将未被标记的进行清除

      • 缺点:
        1.效率低,如果堆中存在大量的对象,而且大部分需要清除,这是需要大量的标记和清除动作,导致标记和清除两个过程的执行效率都随着对象数据量增长而降低.
        2.内存空间碎片话问题.如图↓↓↓清除之后产生大量的不连续的内存碎片,如果此时需要一个比较大的连续内存空间,导致无法分配,将再次执行垃圾回收
        在这里插入图片描述
    • 标记 - 复制算法
      "半区复制"算法,经过GC Root调用链后,将"存活"和"需回收"的分别进行标记,然后复制到另一半,并对"存活"的内存移动堆指针.

      • 缺点:
        1.需要预留一般的空间供存活对象使用,导致内存空间只能使用一半,而且GC执行的频率会增加
        2.如果存活对象较多的情况下,需要复制较多的对象,效率降低
        3.老年代区域的对象大部分都是存活的,无法在老年代使用
        在这里插入图片描述
    • 标记 - 整理算法
      与标记清楚算法的差异在于标记整理算法是移动式的回收算法.

      • 优缺点并存:
        移动后会内存空间分配会更简单,但是移动时会更复杂,但是不移动会增加垃圾回收的频率,综合对比,移动对象更划算.
        在这里插入图片描述

    垃圾回收器:

    jdk1.8默认使用 Parallel Scavenge GC 和 ParallelOld GC
    jdk9开始默认使用的是 G1 
    jdk14弃用了 Parallel Scavenge GC 、ParallelOld GC
    jdk14移除了 GMS GC
    
    • 1
    • 2
    • 3
    • 4
    • Parallel Scavenge GC
      特点:

      • 可控吞吐量
        吞吐量=运行用户代码时间/(运行用户代码时间+垃圾回收时间)*100%
        如:jvm总运行100分钟,垃圾回收为1分钟,吞吐量 :
        99/(99+1)*100% = 99%
      • 自适应调节策略,自动指定新生代、Eden、Survivor区的比例

      相关参数:

      • 使用方式: -XX:+UseParallelGC
      • 最大垃圾收集停顿时间:-XX:MaxGCPauseMillis 参数是大于0的毫秒值
      • 吞吐量大小:-XX:GCTimeRatio 参数是 0~100 之间的整数,也就是垃圾回收时间占总时间的比例.公式: 1/(1+n)*100% ,如设置 n = 9 那么最大垃圾收集时间占总时间的比例为 : 1/(1+9)*100% = 10% ;默认值为 99 , 即允许垃圾回收的时间最大为 1%.
      • 设置年轻代线程数:-XX:ParllGCThreads 当cpu<=8时,默认与cpu核数相同;当cpu>8时,设置为 3+(5*cpu核数)/8
      • 自适应调节:-XX:UseAdaptiveSizePolicy
    • ParallelOld GC
      ParallelOld GC是在jdk1.6后推出的,适合和Parallel Scavenge GC搭配使用.多线程执行垃圾回收效率更高

    • G1 GC
      G1(Garbage First)
      特点:

      • G1把内存划分为多个独立的区域Region(单个最大32M,共2048个分区)

      • G1仍然保留新生代和老年代的思想,但是他们不再是物理隔离,而是一部分Region的集合

      • G1能够充分利用多CPU、多核环境的硬件优势,尽量缩短STW

      • G1整体采用标记整理算法,局部采用复制算法,不会产生内存碎片

      • G1停顿可预测,能够指定一个时间段内,消耗在垃圾收集上的时间基本不会超过设置的时间

      • G1跟踪各个Region里面的垃圾价值大小,会维护一个优先回收列表,每次根据允许的时间来回收最大价值的区域,从而保证在有限时间内将垃圾回收效率最大化
        在这里插入图片描述
        humongous放至比较大的对象,超过1.5个Region

        将整个堆区域划分为与2048个大小相同的Region块,每个块根据对空间实际大小而定,为2的N次幂,即1MB,2MB,4MB,8MB,16MB…

      • G1提供了两种GC模式,Young GC和Mixed GC,两种均执行STW

        • Young GC:选定所有年轻代的Region.通过控制年轻代的Region个数,即控制年轻代内存大小,来控制Young GC的时间开销.
        • Mixed GC:选定所有年轻代的Region,外加 global concurrent marking 统计得出价值最高的若干个老年代Region.
      • G1 GC垃圾回收的四个过程

        • 初始标记:通过’三色标记’来标记GC Root直接关联的对象
        • 并发标记:进行GC Root Traceing过程,线程执行过程中同时进行标记
        • 最终标记:修正并发标记期间,因程序运行导致发生变化的那一部分对象
        • 筛选回收:根据时间来进行价值最大化收集
      • 相关参数:
        -XX:UseG1GC 使用G1垃圾收集器
        -XX:MaxGCPauseMillis=200 设置期望GC最大停顿时间(毫秒)
        -XX:InitiatingHeapOccupancyPercent=45 当老年代占比达到整个堆大小的阈值时,将会触发一次Mixed GC,默认为45%
        -XX:NewRatio=2 新生代与老年代大小的比例,默认为2 即1:2
        -XX:SurvivorRatio=8 eden/survivor空间的比例,默认为8 即:8:1:1 (eden:s0:s1)
        -XX:ParallelGCThreads=n 设置垃圾收集器在并行阶段使用的线程数,默认值随JVM运行的平台而不同
        -XX:ConcGCThreads=n 并发垃圾收集器使用的线程数,默认值随JVM运行的平台而不同
        -XX:G1ReservePercent=n 设置堆内存的预留值,默认为10%
        -XX:G1HeapRegionSize=n 使用G1时Java堆会被分为大小统一的Region区.此参数指定每个Region区的大小,默认根据heap size(最大为2048)算出最优解.如8G/2048=2Mb.最小值为1Mb,最大值为32Mb


    JVM常用指令

    • JVM调优几个指标:
      吞吐量: 即CPU用于运行用户代码的时间与CPU总消耗时间的比值 (吞吐量=运行用户代码时间/(运行用户代码时间+GC回收时间)*100%).如JVM共运行100分钟,GC回收耗时1分钟,吞吐量=99/(99+1)*100=99%
      暂停时间: 执行垃圾回收时,STW停止的时间
      内存占用: java堆栈内存的大小
      收集频率: 垃圾收集的频次
    • 常用指令:
      • jps:显示类名称

        jps -l:显示进程id,主类全路径名或jar路径
        jps -q:显示进程id
        jps -m:显示进程id,显示JVM启动时传递给main()方法的参数
        jps -v:显示进程id,显示JVM启动时显示指定的JVM参数
        可以使用组合命令,如   jps -lmv
        
        • 1
        • 2
        • 3
        • 4
        • 5
      • jinfo是用来查看JVM参数和动态修改部分JVM参数的命令

        jinfo :输出所有的系统属性和参数
        jinfo -flag  :打印指定名称的参数 ---> 如果结果为 -XXX 说明未启用 +XXX 为启用
        jinfo -flag +/-  :打开或关闭参数 +打开 -关闭
        jinfo -flag = :设置参数
        jinfo -flags :打印所有参数
        
        • 1
        • 2
        • 3
        • 4
        • 5
      • jstat用来查看JVM运行时的状态信息,包括内存状态、垃圾回收等
        命令格式: jstat [具体命令] id [间隔毫秒值] [执行次数] 执行次数:默认一直打印,如:jstat -gc 1009 300 20 即执行20次该命令,每次间隔300毫秒

        jstat -class id :统计class loader的具体行为
        jstat -compiler id :统计Hotspot JIT编译器的具体行为
        jstat -gc id :垃圾回收堆的行为统计
        jstal -gcutil id :垃圾回收统计概述
        
        • 1
        • 2
        • 3
        • 4
      • jstack用来查看JVM线程快照的命令,线程快照是当前JVM线程正在执行的方法堆栈集合.使用jstack命令可以定位线程出现长时间卡顿的原因,如死锁,死循环等jstack还可以查看程序崩溃时生成的core文件中的stack信息.

        jatack -F id :当使用jstack无响应时,使用 F 可以强制输出线程堆栈
        jatack -m :同时输出java堆栈和C/C++堆栈信息
        jatack -l :同时输出堆栈信息外,还显示关于锁的附加信息
        
        • 1
        • 2
        • 3

        相关工具Process Explorer v16.43 点击下载

      • jmap可以生成 java 程序的 dump 文件, 也可以查看堆内对象示例的统计信息、查看 ClassLoader 的信息以及finalizer 队列

        jmap -heap :打印java heap摘要
        jmap -histo[:live] :打印堆中的java对象统计信息
        jmap -clstats :打印类加载器统计信息
        jmap -finalizerinfo :打印在 F-Queue 中等待执行finalizer方法的对象
        jmap -dump :生成java堆的dump文件
              dump -live :只转存存活的对象,如果没有指定则转存所有对象
              dump -format=b 二进制格式
              dump -file= 转存文件到指定位置
              如: jmap -dump:live,format-b,file=f:/dump.bin 899
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
      • jhat是用来分析jmap生成dump文件的命令, jhat内置了应用服务器, 可以通过网页查看dump文件分析结果, jhat一般是用在离线分析上.

        jhat 路径
        如: jhat f:/dump.bin
        
        • 1
        • 2

    JVM常用工具

    • VisualVM
      JDK8自带jvisualvm,在bin目录下,高版本需要单独下载
      推荐安装Visual GC插件,是一款可视化的垃圾回收监控工具
    • 阿里巴巴开源Arthas
      点击跳转下载页
    • GC常用指令
      -XX:+PrintGCDetails :打印GC详细信息
      -XX:+PrintGCDateStamps :输出GC的时间戳(以日期的形式)
    • GC日志分析工具
      • 在线版
        直接上传即可
      • GCViewer
        需要打包成jar,然后运行jar,再传入gc.log文件

    其他章节 -> 跳转

    end...
    
    • 1
  • 相关阅读:
    DRM中render-node编号的分配
    分布式架构(分布式ID+分布式事务)
    最新阿里云ECS服务器S6/C6/G6/N4/R6/sn2ne/sn1ne/se1ne处理器CPU性能详解
    语言模型|第三章|大模型训练与微调
    css3新增伪类有哪些?
    8.云原生-Kubesphere3.3.0使用DevOps部署RuoYi 微服务版(下篇)
    我的创作纪念日
    Spring之AOP
    Windows系统创建Python虚拟环境
    牛客小白赛60(F.被抓住的小竹)&61(E.排队)(数学+推公式)
  • 原文地址:https://blog.csdn.net/weixin_45881674/article/details/126589455