美文网首页
2020-12-27 JVM--垃圾收集算法和对象生命周期介绍

2020-12-27 JVM--垃圾收集算法和对象生命周期介绍

作者: 竹blue | 来源:发表于2020-12-27 18:08 被阅读0次

    JVM参数

    标准参数

    标准参数:不随JDK版本变化而变化的参数

    常见:
    ​ -version
    ​ -help
    ​ -server
    ​ -cp

    非标准参数

    非标准参数:随着JDK版本而略有区别。

    -X参数

    -XX参数

    主要用于JVM调优和debug。

    分为两种类型:布尔类型name = value

    1. Boolean类型

      格式:-XX:[+-]<name> +或-表示启用或者禁用name属性

      比如:-XX:+UseConcMarkSweepGC 表示启用CMS类型的垃圾回收器

      ​ -XX:+UseG1GC 表示启用G1类型的垃圾回收器

    2. 非Boolean类型

      格式:-XX<name>=<value>表示name属性的值是value

      比如:-XX:MaxGCPauseMillis=500

    其他参数

    -Xms1000M = -XX:InitialHeapSize=1000M

    -Xmx1000M = -XX:MaxHeapSize=1000M

    -Xss100 = -XX:ThreadStackSize=100

    默认以KB为单位

    1. 1Byte(字节)=8bit(位)
    2. 1KB=1024Byte(字节)
    3. 1MB=1024KB
    4. 1GB=1024MB
    5. 1TB=1024GB

    查看参数

    java -XX:+PrintFlagsFinal -version > flags.txt :将参数打印输出到flags.txt文件中。

    JVM参数修饰符的含义

    设置参数的常见方式

    常见参数的含义

    垃圾收集器

    垃圾收集算法是方法论,垃圾收集器是落地实现


    垃圾收集器

    Serial

    Serial收集器是一种单线程收集器,STW

    • 优点:简单高效,拥有很高的单线程收集效率

    • 缺点:收集过程需要暂停所有线程

    • 算法:复制算法

    • 适用范围:新生代

    • 应用:Client模式下的默认新生代收集器

    • 执行过程:

      Serial GC

    Serial Old

    Serial Old收集器是Serial收集器的老年代版本,也是一个单线程收集器,不同的是采用"标记-整理算",STW。

    执行过程:

    Serial Old

    ParNew

    ParNew 可以理解为是Serial的多线程版本,是并行垃圾收集器。STW,默认开启的线程数 = 多核CPU的线程,可以通过参数:-XX:ParallelGCThreads 来控制开启的线程数

    • 优点:在多CPU时,比Serial效率高。

    • 缺点:收集过程暂停所有应用程序线程,单CPU时比Serial效率差。

    • 算法:复制算法

    • 适用范围:新生代

    • 应用:运行在Server模式下的虚拟机中首选的新生代收集器

      执行过程:


      ParNew
      注意点:
      1. STW: stop the world 表示:应用程序的线程和垃圾收集的线程串行执行。
      2. 并行:是指垃圾收集器的线程并行的执行。
      3. 并发:垃圾收集器线程和应用程序线程一起跑,或者是一些步骤可以一起跑。
      

    Parallel Scavenge

    Parallel Scavenge收集器是一个新生代收集器,它也是使用复制算法的收集器,又是并行的多线程收集 器,看上去和ParNew一样,但是Parallel Scanvenge更关注系统的吞吐量

    具体是通过参数:-XX:MaxGCPauseMillis : 停顿时间 和 -XX:MaxGCTimeRatio 吞吐量大小 来控制。

    • -XX:MaxGCPauseMillis : 停顿时间, 取值: > 0

    • -XX:MaxGCTimeRatio: 吞吐量大小, 取值:0 ~100 例如:19 = 1/(19+1) = 5% 吞吐量

      -XX:UserApaptiveSizePolicy :是一个boolear值,打开以后自动调整新生代的大小。

    吞吐量=运行用户代码的时间/(运行用户代码的时间+垃圾收集时间)

    比如虚拟机总共运行了100分钟,垃圾收集时间用了1分钟,吞吐量=(100-1)/100=99%。

    若吞吐量越大,意味着垃圾收集的时间越短,则用户代码可以充分利用CPU资源,尽快完成程序 的运算任务。

    Parallel Old

    Parallel Old收集器是Parallel Scavenge收集器的老年代版本,使用多线程和标记****-****整理算法进行垃圾回

    收,也是更加关注系统的吞吐量

    CMS

    CMS(Concurrent Mark Sweep)收集器是一种以获取 最短回收停顿时间 为目标的收集器。 采用的是"标记-清除算法",整个过程分为4步。

    1. 初始标记 CMS initial mark
    2. 并发标记 CMS concurrent mark
    3. 重新标记 CMS remark
    4. 并发清除 CMS concurrent sweep 清除不可达对象回收空间,同时有新垃圾产生,留着下次清理称为 浮动垃圾

    由于整个过程中,并发标记和并发清除,收集器线程可以与用户线程一起工作,所以总体上来 说,CMS收集器的内存回收过程是与用户线程一起并发地执行的。

    • 执行过程:
    CMS垃圾收集器
    • 优点:并发收集、低停顿

    • 缺点:产生大量空间碎片、并发阶段会降低吞吐量,还会并发失败

    • CMS 存在两种主要的工作模式:

      backgroud模式为正常模式执行上述的CMS GC流程

      -XX:+CMSParalleInitialMarkEnabled :初始标记是否开启多线程, 1.7 默认单线程; 1.8:默认多线程
      

      forefroud模式为Full GC模式

      CMS常见设置的参数:

      -XX:CMSInitiatingOccupancyFraction CMS回收阈值,默认值 -1 //取值0-100,按百分比回收
      -XX:+UseCMSInitiatingOccupancyOnly 辅助参数,如果不开启上面参数只会使用一次就恢复自动调整。

      CMS扫描线程默认2s一次,如果1s就达到阈值,这时候需要再等1s垃圾才会回收。

      当创建对象太多导致backgroud模式 GC失败,这时候就会切换到forefroud模式同时会启用Serial Old 代替CMS将系统STW,重新进行GC Root 并进行一次Full GC。

      forefroud 会进行MSC策略,涉及到的两个参数是:

      • -XX:+UseCMSCompactAtFullCollection 几次Full GC整理我们内存

      • -XX:CMSFullGCsBeforeCompaction = 0 表示0次之后整理内存

        问题1:场景:新生代执行老年代场景,如何处理?

        解决办法:并发预处理:在重新标记之前,对新生代对象进行一次Minor GC,来解决全堆扫描的问题。

        对应参数是:

        1. -XX:CMSScheduleRemarkEdenSizeThreshold 默认:= 2M
        2. -XX:CMSScheduleRemarkEdenPenetration 默认:= 50%

        意思是:Eden区大小从2M开始扫描,内存占比到达50%结束 -- 这个策略也叫做可中止的预处理。这段时间如果触发Minor GC 就会进入重新标记阶段,如果没有触发默认等待5s,进入重新标记阶段。

        参数:-XX:CMSMaxAbortablePreclean 默认 = 5s

        Young区指向Old区的引用发生变化

        问题2:针对老年代如何处理 全Old区扫描的问题?

        解决办法: 首先会将老年代划分为512K 的块,然后将对象引用关系的变化记录到 Card Table (参考:单次遍历算法),并将对应的块记录为dirty Card,当进入重新标记的时候会重新进行标记并清除Card Table 中的 dirty Card。

        Old区内引用对象发生变化处理办法

        Card Table作用:1. 记录Old区对象引用的变化;2. 记录Old区对象对新生代的引用。

    • CMS垃圾收集器的相关参数

      相关参数:
      //开启CMS垃圾收集器
      -XX:+UseConcMarkSweepGC
      //默认开启,与-XX:CMSFullGCsBeforeCompaction配合使用 -XX:+UseCMSCompactAtFullCollection
      //默认0 几次Full GC后开始整理
      -XX:CMSFullGCsBeforeCompaction=0 //辅助CMSInitiatingOccupancyFraction的参数,不然CMSInitiatingOccupancyFraction只会使用一次就恢复自动调整,也就是开启手动调整。
      -XX:+UseCMSInitiatingOccupancyOnly
      //取值0-100,按百分比回收
      -XX:CMSInitiatingOccupancyFraction 默认-1
      
      注意:CMS并发GC不是“full GC”。HotSpot VM里对concurrent collection和full collection有明确的区分。所有带有“FullCollection”字样的VM参数都是跟真正的full GC相关,而跟CMS并发GC无关的。
      

    相关文章

      网友评论

          本文标题:2020-12-27 JVM--垃圾收集算法和对象生命周期介绍

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