JVM系列(七)之调优基础知识和PS+PO调优

2021/03/29 JVM 共 1961 字,约 6 分钟

本篇将会简单的介绍调优的基础知识,顺便讲解PS+PO垃圾回收器的调优

调优的基本概念

内存大小与垃圾回收器

  • Serial:几十兆
  • Parallel:几百兆—几个G
  • ParNew+CMS:几个G—20G
  • G1:上百G
  • ZGC:4T—16T

简单指令

  • -XX:+PrintCommandLineFlags:展示打印基础信息

    image

  • -XX:+UseSerialGC = Serial New (DefNew) + Serial Old :使用SerialGC

    • 小型程序。默认情况下不会是这种选项,HotSpot会根据计算及配置和JDK版本自动选择收集器
  • -XX:+UseParNewGC = ParNew + SerialOld
    • 这个组合已经很少用(在某些版本中已经废弃)
    • https://stackoverflow.com/questions/34962257/why-remove-support-for-parnewserialold-anddefnewcms-in-the-future
  • -XX:+UseConc(urrent)MarkSweepGC = ParNew + CMS + Serial Old

    • 红色括号的意思是有些JVM中需要加上红色部分,某些不需要
  • -XX:+UseParallelGC = Parallel Scavenge + Parallel Old (1.8默认) 【PS + SerialOld】

  • -XX:+UseParallelOldGC = Parallel Scavenge + Parallel Old

  • -XX:+UseG1GC = G1

  • Linux中没找到默认GC的查看方法,而windows中会打印UseParallelGC
    • java +XX:+PrintCommandLineFlags -version
    • 通过GC的日志来分辨

名词介绍

  • 吞吐量:用户代码执行时间 / (用户代码执行时间 + 垃圾回收时间)
  • 响应时间:stw时间越短,响应时间的表现就越好

GC调优

简单的见识调优

public class HelloGC {
    public static void main(String[] args) {
        System.out.println("Hello GC!");

        List list = new LinkedList();
        for(;;) {
            byte[] b = new byte[1024*1024];
            list.add(b);
        }
    }
}

image

  • 我们可以发现,最初时我们设置堆的初始和最大值都是一样的,这样其实是可以避免堆空间动态改变的,如果堆空间可以动态扩容的话,那么会对性能有一定影响,因为这个堆空间除了会扩大以外,还会自己变小

GC日志详解

上图中我们使用了命令-X:+PrintGC ,这一次我们稍微更换一下命令,使用-X:+PrintGCDetails

image

  • 我们看这个GC日志的详情,介绍一下这里面的意思
    • 第一个参数,GC,意思是调用了YGC,如果是FGC就意味着调用了FGC
    • 第二个参数,Allocation Failure,意思是调用GC的原因,这里的原因就是空间分配不下了,这里分配到空间是eden空间
    • 第三个参数,7584k->258K(9216K),0.0146063,意思是eden空间达到了7584k,调用GC,将eden中的对象转移到老年代中,转移后只剩下258K占用空间括号中是新生代的最大空间,后面的数字意思是执行时间
    • 第四个参数和第三个参数非常像,第四个参数指的是整个堆空间的占用情况,我们看到,占用量一直增长,这是因为新生代对象被移动到了老年代,所以eden空间被清理,但是整体空间没有清理

image

  • 这部分日志展现的是堆空间的详细信息,首先我们看new generation的空间是18432K,我们将eden空间和一个survivor空间加起来就正好是新生代的空间大小,这里可以佐证:新生代每一次都是回收eden空间和其中一个survivor空间,将这两个空间中的存活对象全部转移到另外一个survivor空间,这就意味着同一时刻只会有一个survivor空间被使用

GC调优常用指令

  • top指令

    这个指令可以将cpu资源占有率按照从高到低的方式排列,非常有用

    image

  • jstack指令

    这个指令可以检测指定pid的java程序,我们用一个死锁作为例子

    image

  • -XX:+HeapDumpOnOutOfMemoryError

    这个参数配置非常有用,执行这个参数后,如果我们的JVM发生了oom错误,就可以将oom错误导出成为一个文件,这个文件就可以使用分析工具来分析

  • jhat

    这个指令就可以用来分析我们的错误日志,通过这种方式来分析错误日志

    image

    image

arthas

  • 有的时候我们在生产环境中需要实时对JVM进行监控,但是我们又不能启动一些图形化界面,这样对效率的影响太大了,这个时候我们就可以选择使用阿里巴巴开源的arthas工具来进行实时监控
  • https://github.com/alibaba/arthas

文档信息

Search

    Table of Contents