zoukankan      html  css  js  c++  java
  • 第一周JVM核心技术-工具与GC策略

    一、 JDK工具

    1.1 内置命令行工具

    工具 简介
    jps/jinfo 查看java进程
    jstat 查看JVM内部GC信息
    jmap 查看JVM堆或类占用空间信息
    jstack 查看线程信息
    jcmd 整合性的命令
    jrunscript/jjs 执行js命令

    1. jps

    查看运行的java进程

    jps

    查看详细的java进程信息

    jps -mlv

    2. jstat

    查看gc详细信息

    jstat -gc pid 1000 100

    pid可以根据jps命令得到,参数里的1000代表每1000毫秒统计一次,100代表统计100次

    查看gc相关区域的使用率

    jstat -gcutil pid 1000 100

    3. jmap

    查看堆内存

    jmap -heap pid
    jmap -histo pid
    jmap -dump:format=b,file=xx.hprof
    pid

    4. jstack

    查看线程的情况

    jstack -l pid

    5. jcmd

    综合命令,能查看堆、线程等情况

    jcmd pid VM.version
    jcmd pid VM.flags
    jcmd pid VM.command_line
    jcmd pid VM.system_properties
    jcmd pid Thread.print
    jcmd pid GC.class_histogram
    jcmd pid GC.heap_info

    6. jrunscript/jjs

    可以运行js脚本

    jrunscript -e "print('abc')"
    jrunscript -l js -f test.js

    1.2 JDK内置图形化工具

    可自行下载了解

    1. jconsole
    2. jvisualvm
    3. VisualGC
    4. jmc

    二、GC的背景与原理

    2.1 识别存活对象

    怎么判断对象没有引用了呢?

    引用计数 -> 引用跟踪

    引用计数:
    引用计数的方法,无法循环调用的情况。如A调用B,B调用C,C调用A。这样他的引用计数永远不会为0,也就不能被回收。

    引用跟踪:
    根据一些GC ROOT对象,向下寻找他们引用的对象。

    可以作为GC ROOT的对象:

    • 当前正在执行的方法里的局部变量和输入参数
    • 活动线程
    • 所有类的静态字段
    • JNI引用

    2.2 GC算法

    1. 清除算法

    标记 - 清除

    1. 复制算法

    标记 - 复制

    1. 整理算法

    标记 - 清除 - 整理

    2.3 垃圾回收器

    1. Serial GC /ParNew GC

    -XX:+UseSerialGC 配置串行 GC

    Serial GC,也叫串行GC。年轻代使用复制算法,老年代使用整理算法。两者都是单线程的垃圾收集器,所以整个过程都是Stop-The-World。这种垃圾回收器适用于几百MB的堆内存,并且单核CPU时比较有用。

    ParNew GC是Serial GC的多线程版本,一般是配合CMS使用。

    2. Parallel GC

    -XX:+UseParallelGC -XX:+UseParallelOldGC

    也叫并行GC,年轻代使用复制算法,老年代使用整理算法。可以通过
    -XX:ParallelGCThreads=N 来指定 GC 线程数, 其默认值为 CPU 核心数

    并行GC适用于多核服务器,主要目标是增加吞吐量。

    • 在GC期间,所有CPU内核都在并发清理垃圾,所以总暂停时间会更短
    • 在两次GC周期的间隔期,没有GC线程在运行,不会消耗任何线程资源
    3. CMS

    -XX:+UseConcMarkSweepGC

    采用的标记清除算法。CMS的设计目标是避免长时间的卡顿。主要通过两种手段达成目标

    • 不对老年代进行整理,而是使用空闲列表管理内存空间的回收
    • 在标记-清除阶段的大部分工作和应用线程是一起并发执行的。

    CMS清理的六个阶段

    • 初始标记 标记根对象和根对象直接引用的对象
    • 并发标记 从前一阶段找到的根对象算起,标记所有存活对象
    • 并发预清理 因为是并发执行的,所以过程中可能有一些引用发生改变,JVM会通过Card的方式需要标记一下,这就是所谓的卡片标记
    • 最终标记 本阶段的目标是完成所有对象的标记。
    • 并发清除 删除不再使用的对象
    • 并发重置 重置CMS算法的内部数据,为下一次GC循环做准备。
    4. G1 GC

    -XX:+UseG1GC -XX:MaxGCPauseMillis=50

    G1的全称是Garbage-First,意为垃圾优先,哪一块垃圾最多就优先清理哪一块。

    G1的设计目标是将STW的时间变成可预期且可配置的。

    他不将堆分为年轻代和老年代,而是划分为多个(通常是2048)可以存放对象的小块区域.每个小块,可能一会被定义为Eden区,一会被定义为老年代。

    这样划分之后,G1就可以不必每次都去收集整个堆空间,而是以增量的方式处理。

    G1清理的阶段

    • 初始标记 此阶段标记所有从GC根对象直接可达的对象。
    • Root区扫描 标记从根区域可达的对象
    • 并发标记
    • 再次标记
    • 清理

    -XX:G1NewSizePercent:初始年轻代占整个 Java Heap 的大小,默认值为 5%;

    -XX:G1MaxNewSizePercent:最大年轻代占整个 Java Heap 的大小,默认值为 60%;

    -XX:G1HeapRegionSize:设置每个 Region 的大小,单位 MB,需要为 1,2,4,8,16,32 中的某个值,默 认是堆内存的 1/2000。如果这个值设置比较大,那么大对象就可以进入 Region 了。

    -XX:ConcGCThreads:与 Java 应用一起执行的 GC 线程数量,默认是 Java 线程的 1/4,减少这个参数的数值可 能会提升并行回收的效率,提高系统内部吞吐量。如果这个数值过低,参与回收垃圾的线程不足,也会导致并行回收机制耗时加长。

    -XX:+InitiatingHeapOccupancyPercent(简称 IHOP):G1 内部并行回收循环启动的阈值,默认为 Java Heap 的45%。这个可以理解为老年代使用大于等于 45% 的时候,JVM会启动垃圾回收。这个值非常重要,它决定了在什么时间启动老年代的并行回收。

    -XX:G1HeapWastePercent:G1停止回收的最小内存大小,默认是堆大小的 5%。GC 会收集所有的Region 中 的对象,但是如果下降到了5%,就会停下来不再收集了。就是说,不必每次回收就把所有的垃圾都处理完,可以遗留少量的下次处理,这样也降低了单次消耗的时间

    -XX:+GCTimeRatio:这个参数就是计算花在 Java 应用线程上和花在 GC 线程上的时间比率,默认是 9,跟新生代内存的分
    配比例一致。这个参数主要的目的是让用户可以控制花在应用上的时间,G1的计算公式是100/(1+GCTimeRatio)。这样如果参数设置为 9,则最多 10% 的时间会花在 GC工作上面。ParallelGC的默认值是 99,表示 1% 的时间被用在 GC 上面,
    这是因为 Parallel GC 贯穿整个 GC,而 G1 则根据 Region来进行划分,不需要全局性扫描整个内存堆。

    -XX:+UseStringDeduplication:手动开启 Java String 对象的去重工作,这个是 JDK8u20 版本之后新增的参数,主要用于
    相同 String 避免重复申请内存,节约 Region 的使用。

    -XX:MaxGCPauseMills:预期 G1 每次执行 GC 操作的暂停时间,单位是毫秒,默认值是 200 毫秒,G1 会尽量保证控制在
    这个范围内

    5. ZGC

    -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -Xmx16g

    主要特点:

    1. GC最大停顿时间不超过10ms
    2. 堆内存支持区域广,小到几百M,大到4TB
    3. 与G1相比,应用吞吐量有下降,但不超过15%
    4. JDk15前仅支持Linux系统

    通过着色指针和读屏障,实现几乎全部的并发执行,几毫秒级别的延迟,线性可扩展;

    多个垃圾回收器对比

    GC如何选择?

    选择正确的GC算法,唯一可行的方式就是实践,一般性的指导准则是:

    1. 如果考虑吞吐量优先,CPU资源最大程度的处理业务,用Parallel GC
    2. 如果考虑系统低延迟,则用CMS
    3. 如果系统堆内存较大,同时希望平均GC时间可控,使用G1 GC。一般超过4G,算是比较大,超过8G ,比如16G-64G,非常推荐G1 GC

    各版本默认垃圾回收器

    版本 垃圾回收器
    JDK1.7 Parallel
    JDK1.8 Parallel
    JDK1.9 G1
    书山有路勤为径,学海无涯苦作舟
  • 相关阅读:
    LeetCode 449. Serialize and Deserialize BST
    LeetCode Word Abbreviation
    LeetCode 402. Remove K Digits
    LeetCode 439. Ternary Expression Parser
    LeetCode Frog Jump
    LeetCode 630. Course Schedule III
    LeetCode 729. My Calendar I
    LeetCode 567. Permutation in String
    LeetCode Find Permutation
    LeetCode Number of Atoms
  • 原文地址:https://www.cnblogs.com/javammc/p/14775080.html
Copyright © 2011-2022 走看看