zoukankan      html  css  js  c++  java
  • 垃圾回收

    1.对象被判定成垃圾的标准

    没有被其他对象引用

    2.判断对象是否为垃圾的算法

    (1)引用计数法

     

    优点and缺点

     

    (2)可达性分析算法

     

    根节点:类加载器、Thread、虚拟机栈的本地变量表、static 成员、常量引用、本地方法栈的变量

    垃圾回收回收算法

    1.标记-清除(Mark and Sweep)

     

    缺点是内存空间碎片化太严重

    2.复制算法(Copying)

    (1)复制算法介绍

     

    (2)复制算法优势

     

    3.标记-整理算法(Compacting)

    (1)标记整理算法介绍

     

    (2)标记整理算法优点

     

    4.分代收集算法

    年轻代用的是复制算法
    老年代 用的是标记清除或者标记整理算法

     

    (2)年轻代内存空间

     

    如果Eden区不能保存一个较大的对象,则会保存到老年代中,默认十五岁之后会转移到老年代中

     

     

      -XX:PretenureSizeThreshold 对象分配:对象优先在 Eden 区分配、大对象直接进入Old 区
    -XX:MaxTenuringThreshold 长期存活对象进入 Old 区
    -XX:+PrintTenuringDistribution如果希望跟踪每次新生代GC后,survivor区中对象的年龄分布,可在启动参数上增加。
    -XX:TargetSurvivorRatio
    设定survivor区的目标使用率。默认50,即survivor区对象目标使用率为50%。
    为什么要动态的计算tenuring threshold的值呢?假设有很多年龄还未达到TenuringThreshold的对象依旧停留在survivor区,这样不利于新对象从eden晋升到survivor。因此设置survivor区的目标使用率,当使用率达到时重新调整TenuringThreshold值,让对象尽早的去old区。


    (1)GC分类

     

    从年轻代空间(包括 Eden 和 Survivor 区域)回收内存被称为 Minor GC
    Full GC 是清理整个堆空间—包括年轻代和老年代。

    Major GC 是清理老年代

     JVM中的堆,一般分为三大部分:新生代、老年代、永久代:

    永久代

        指内存的永久保存区域,主要存放Class和Meta(元数据)的信息,Class在被加载的时候被放入永久区域. 它和和存放实例的区域不同,GC不会在主程序运行期对永久区域进行清理。所以这也导致了永久代的区域会随着加载的Class的增多而胀满,最终抛出OOM异常。

        在Java8中,永久代已经被移除,被一个称为“元数据区”(元空间)的区域所取代。

     

    (3)对象如何晋升到老年代

     

    (4)设置参数

     

    (5)触发full GC的方法

     

    5.stop-theWorld

     

    6.Safepoint

     

    从线程角度看,safepoint可以理解成是在代码执行过程中的一些特殊位置,当线程执行到这些位置的时候,说明虚拟机当前的状态是安全的,如果有需要,可以在这个位置暂停,比如发生GC时,需要暂停暂停所以活动线程,但是线程在这个时刻,还没有执行到一个安全点,所以该线程应该继续执行,到达下一个安全点的时候暂停,等待GC结束。

    JVM有两种运行模式Server与Client。两种模式的区别在于,Client模式启动速度较快,Server模式启动较慢;但是启动进入稳定期长期运行之后Server模式的程序运行速度比Client要快很多。这是因为Server模式启动的JVM采用的是重量级的虚拟机,对程序采用了更多的优化;而Client模式启动的JVM采用的是轻量级的虚拟机。所以Server启动慢,但稳定后速度比Client远远要快。

    1. 当前是Client or Server?

    使用Java -version命令就能显示出当前虚拟机处于哪种模式。 
    Client: 
    如下图所示,可以看到HotSpot虚拟机采用Client模式启动的。 
    这里写图片描述

    垃圾回收器分类

    串行收集器
    单线程收集器
    Serial::Serial, Serial Old

    并行收集器
    吞吐量优先 是说垃圾收集线程之间并行工作 用户线程处在等待状态 适合交互性比较弱的场景
    吞吐量:花在垃圾收集的时间和花在应用时间的占比 -XX:GCTimeRatio=<n>,垃圾收集时间占1/(1+n)
    Parallel(吞吐量优先, Server 模式默认收集器):Parallel Scavenge, Parallel Old
    并发收集器
    并发收集器 停顿时间优先 垃圾收集线程和用户线程一起执行 适合对相应时间有要求的场景
    停顿时间:垃圾收集器做垃圾回收中断应用执行的时间 -XX:MaxGCPauseMillis
    Concurent(停顿时间优先):CMS , G1

    如何选择垃圾收集器?

    1. 优先调整堆的大小让服务器自己来选择

    2. 如果内存小于100M,使用串行收集器

    3。 如果是单核,并且没有停顿时间的要求,选择串行或者 JVM 自己选

    4. 如果允许停顿时间超过1秒,选择并行或 JVM 自己选

    5. 如果响应时间最重要,并且不能超过1秒,使用并发收集器



    
    

    垃圾回收之新生代垃圾收集器

     

    
    

    2.Serial收集器(复制算法-单线程-Client模式)

     

    2.ParNew收集器(复制算法-多线程-Client模式)

     

    3.Parallel Scavenge收集器(复制算法-多线程-Server模式下)

     

     

     

    垃圾回收之老年代垃圾收集器

    1.Serial Old收集器(标记整理算法-单线程-Client模式下)

     

    2.Paraller Old收集器(标记整理算法-多线程-)

     

    3.CMS收集器(标记清除算法)

     

    4.G1收集器(新生代,老年代都可以用)

     

    G1的几个概念

    Region

    SATB:Snapshot-At-The-Beginning,它是通过 Root Tracing 得到的,GC 开始时候存活对象的快照。

    RSet:记录了其他 Region中的对象引用本 Region 中对象的关系,属于 points-into 结构

    YoungGC

    新对象进入 Eden 区

    存活对象拷贝到Survivor 区

    存活时间达到年龄阈值时,对象晋升到 Old 区

    MixedGC

    不是 FullGC,回收所有的 Young和所有的 Old

    global concurrent marking

    1. Initial marking phase: 标记 GC Root, STW

    2. Root region scanning phase:标记存活 Region

    3. Concurrent marking phase:标记存活的对象

    4. Remark phase:重新标记,STW

    5. Cleanup phase:部分 STW

    MixedGC时机

    InitiatingHeapOccupancyPercent

    G1HeapWastePercent

    G1MixedGCLiveThresholdPercent

    G1MixedGCCountTarget

    G1OldGCSetRegionThresholdPercent

    -XX:+UseG1GC 开启 G1

    -XX:G1HeapRegionSize=n, Region 的大小,1-32M,最多2048个

    -XX:MaxGCPauseMillis=200 最大停顿时间

    -XX:G1NewSizePercent、-XX:G1MaxNewSizePercent

    -XX:G1ReservePercent=10 保留防止 to space溢出

    -XX:ParallelGCThreads=n SWT线程数

    -XX:ConcGCThreads=n 并发线程数=1/4*并行

    最佳实践

    年轻代大小:避免使用-Xmn, -XX:NewRatio 等显式 Young 区大小,会覆盖暂停时间目标

    暂停时间目标:暂停时间不要太严苛,其吞吐量目标是90%的应用程序时间和10%的垃圾回收时间,太严苛会直接影响到吞吐量

    需要切换到 G1的情况:

    1. 50%以上的堆被存活对象占用

    2. 对象分配和晋升的速度变化非常大

    3. 垃圾回收时间特别长,超过了1秒

    可视化 GC 日志分析工具

    打印日志相关参数:

    -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:$CATALINA_HOME/logs/gc.log -XX:+PrintHeapAtGC -XX:+PrintTenuringDistribution

    例(默认为 ParallelGC, 其它的添加-XX:+UseConcMarkSweepGC或-XX:+UseG1GC即可):

    JAVA_OPTS="$JAVA_OPTS -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:$CATALINA_HOME/logs/gc.log"

    CMS日志格式
    G1日志格式

    在线工具:http://gceasy.io/

    访问 GCeasy 官网导入日志即可获取可视化分析及优先建议

    GCeasy 日志

    GCViewer

    mvn clean package -Dmaven.test.skip 生成 jar包,双击执行,导入日志即可进入图形化分析页面

    GCViewer

  • 相关阅读:
    Python range 函数 Python零基础入门教程
    Python eval 与 exec 函数的区别 Python零基础入门教程
    Python callable 函数 Python零基础入门教程
    Python bytes 函数 Python零基础入门教程
    Python ord 函数 Python零基础入门教程
    Python len函数 Python零基础入门教程
    第十二课 通过URL api拿到接送数据并做页面展示
    第十三课 axios请求数据
    网络编程学习路线计划
    erlang学习笔记本【不断更新】
  • 原文地址:https://www.cnblogs.com/zyy1688/p/10830467.html
Copyright © 2011-2022 走看看