java虚拟机10

JDK为我们提供的工具

  • 命令行工具
    • jps:虚拟机进程状况工具
    • jstat:虚拟机统计信息监视工具
    • jinfo:java配置信息工具
    • jmap:java内存映像工具
    • jhat:虚拟机堆转储快照分析工具
    • jstack:java堆栈跟踪工具
  • 可视化工具
    • JConsole:java监视与管理控制台
    • VisualVM:多合一故障处理工具

jps

  • 第一列代表进程号,后面代表具体的进程,但是第二列可能空缺

  • jps -q 只显示进程号

  • jps -m 显示更多信息

  • jps -l 显示全路径的主类

  • jps -v 显示虚拟机参数

jstat

  • jstat -class 进程号

    • 统计类加载器

    • Loaded  Bytes  Unloaded  Bytes     Time
         656  1316.5        0     0.0       0.39
      
  • jstat -gc 进程号

    • 统计垃圾回收信息

    • S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT
      461312.0 461312.0  0.0    0.0   353792.0 91989.1  1954304.0  1045609.1  4864.0 3971.0 512.0  439.1      27    2.377   7      2.064    4.441
      
    • S0C:代表survivor0的容量

    • S1C:代表survivor1的容量

    • S0U:代表survivor0已使用的空间

    • S1U:代表survivor1已使用的空间

    • EC:eden区的容量

    • EU:eden区已使用的容量

    • OC:老年代的容量

    • OU:老年代的使用量

    • MC:方法区的容量

    • MU:方法区的使用量

    • CCSC:压缩类?

    • CCSU:

    • YGC:young gc的次数

    • YGCT:young gc花费的时间

    • FGC:full gc的次数

    • FGCT:full gc花费的时间

    • GCT:

  • 显示的实时数据,还需要统计数据

  • jstat -gc 进程号 1000 10:隔1000ms刷新10次

    • S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT
      461312.0 461312.0  0.0   126592.0 462336.0 443850.8 2383872.0   757406.3  4864.0 3971.0 512.0  439.1      61    7.925  13      4.423   12.348
      461312.0 461312.0 196992.0 126592.0 462336.0 462336.0 2383872.0   890654.3  4864.0 3971.0 512.0  439.1      62    7.925  13      4.423   12.348
      461312.0 461312.0 461312.0  0.0   462336.0 36987.6  2383872.0   894694.3  4864.0 3971.0 512.0  439.1      62    8.115  13      4.423   12.538
      461312.0 461312.0 461312.0  0.0   462336.0 64728.2  2383872.0   894694.3  4864.0 3971.0 512.0  439.1      62    8.115  13      4.423   12.538
      461312.0 461312.0 461312.0  0.0   462336.0 101715.7 2383872.0   894694.3  4864.0 3971.0 512.0  439.1      62    8.115  13      4.423   12.538
      461312.0 461312.0 461312.0  0.0   462336.0 129456.4 2383872.0   894694.3  4864.0 3971.0 512.0  439.1      62    8.115  13      4.423   12.538
      461312.0 461312.0 461312.0  0.0   462336.0 157197.0 2383872.0   894694.3  4864.0 3971.0 512.0  439.1      62    8.115  13      4.423   12.538
      461312.0 461312.0 461312.0  0.0   462336.0 194184.6 2383872.0   894694.3  4864.0 3971.0 512.0  439.1      62    8.115  13      4.423   12.538
      461312.0 461312.0 461312.0  0.0   462336.0 221925.2 2383872.0   894694.3  4864.0 3971.0 512.0  439.1      62    8.115  13      4.423   12.538
      461312.0 461312.0 461312.0  0.0   462336.0 249665.9 2383872.0   894694.3  4864.0 3971.0 512.0  439.1      62    8.115  13      4.423   12.538
      

VM参数分类

  • 官网地址

    • https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html#BABDJJFI
  • 标准选项:所有的实现都支持,-开头

    • -d32
  • 非标准选项,-X开头,特定的Hotspot都支持,有可能变化

    • -Xms
    • -Xmx
  • 高级运行时选项,-XX开头,是最复杂,变化最多的选项,针对高级开发人员做调整的,不同版本不同厂家是有区别的

jinfo

  • 玩jvm的参数配置

  • windows环境下:

  • java -XX:+PrintFlagsFinal -version,高级选项的参数全部打印了出来

  • jinfo -flags 进程号

    • Attaching to process ID 4564, please wait...
      Debugger attached successfully.
      Server compiler detected.
      JVM version is 25.162-b12
      Non-default VM flags: -XX:CICompilerCount=4 -XX:InitialHeapSize=266338304 -XX:MaxHeapSize=4255121408 -XX:MaxNewSize=1418199040 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=88604672 -XX:OldSize=177733632 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
      Command line:  -Dvisualvm.id=514892469556800 -javaagent:E:\ITSoftware\JetBrains\IntelliJ IDEA 2019.1.3\lib\idea_rt.jar=4234:E:\ITSoftware\JetBrains\IntelliJ IDEA 2019.1.3\bin -Dfile.encoding=UTF-8
      
    • 把当前进程中JVM的配置参数打印了出来,其余的高级参数全部设置的默认值

  • jinfo -flag PrintGC 进程号

    • 显示当前PrintGC 选项的状态
  • jinfo -flag +PrintGC 进程号

    • 动态开启PrintGC
    • 同理+变成-,就是关闭PrintGC

jmap

  • Dump日志,jmap最大的功能是生成一个堆转储快照,简称dump或heapdump文件

    • 在运行时数据区中进行了各种划分,这就是JVM中的内存,很多时候宕机了为了分析问题,我们需要把JVM的运行时内存以文件形式导出来
  • jmap -heap 进程号

    • Attaching to process ID 4564, please wait...
      Debugger attached successfully.
      Server compiler detected.
      JVM version is 25.162-b12
      
      using thread-local object allocation.
      Parallel GC with 10 thread(s)
      
      Heap Configuration:
         MinHeapFreeRatio         = 0
         MaxHeapFreeRatio         = 100
         MaxHeapSize              = 4255121408 (4058.0MB)
         NewSize                  = 88604672 (84.5MB)
         MaxNewSize               = 1418199040 (1352.5MB)
         OldSize                  = 177733632 (169.5MB)
         NewRatio                 = 2
         SurvivorRatio            = 8
         MetaspaceSize            = 21807104 (20.796875MB)
         CompressedClassSpaceSize = 1073741824 (1024.0MB)
         MaxMetaspaceSize         = 17592186044415 MB
         G1HeapRegionSize         = 0 (0.0MB)
      
      Heap Usage:
      PS Young Generation
      Eden Space:
         capacity = 473432064 (451.5MB)
         used     = 217782608 (207.6936798095703MB)
         free     = 255649456 (243.8063201904297MB)
         46.00081501873097% used
      From Space:
         capacity = 472383488 (450.5MB)
         used     = 472383488 (450.5MB)
         free     = 0 (0.0MB)
         100.0% used
      To Space:
         capacity = 472383488 (450.5MB)
         used     = 0 (0.0MB)
         free     = 472383488 (450.5MB)
         0.0% used
      PS Old Generation
         capacity = 2836922368 (2705.5MB)
         used     = 1157876008 (1104.2366104125977MB)
         free     = 1679046360 (1601.2633895874023MB)
         40.81451156579551% used
      
      3156 interned Strings occupying 258984 bytes.
      
    • 打印全部堆的情况

  • jmap -histo 进程号

    • 打印启动进程里面,按实际数量的排名,以及这些实例占用的空间大小
  • jmap -histo:live 进程号

    • 只统计存活的对象
    • [B表示byte数组
  • 在linux下:

    • jmap -histo:live | head -20
    • 只显示前20个
  • jmap -dump

    • 如果服务器磁盘不够,不要使用这个命令,JVM内存多大,这个文件就有多大,并且这个命令很消耗性能,所以一般情况或者服务器高峰时期不要使用这个命令
  • jmap -dump:live,format=b,file=G:\king.bin 进程号

    • 存活对象、文件格式是比特、文件名是king.bin并在G盘下
  • 导出的文件可以用visualvm来查看

jhat

  • 不推荐使用,因为在winodws上有可视化工具
  • jhat king.bin
    • 后面跟的是生成的dump文件名
    • 在7000端口生成了http服务器,但是信息不容易看懂
  • 用visualvm查看更方便

jstack

  • jstack 进程号

  • 显示线程相关信息

  • jstack最大的作用是去排除死锁

    • package ex10;
      
      /**
       *类说明:演示死锁的产生
       */
      public class NormalDeadLock {
              
              
      
          private static Object No13 = new Object();//第一个锁
          private static Object No14 = new Object();//第二个锁
      
          //第一个拿锁的方法
          private static void peterDo() throws InterruptedException {
              
              
              String threadName = Thread.currentThread().getName();
              synchronized (No13){
              
              
                  System.out.println(threadName+" get NO13");
                  Thread.sleep(100);
                  synchronized (No14){
              
              
                      System.out.println(threadName+" get NO14");
                  }
              }
          }
      
          //第二个拿锁的方法
          private static void kingDo() throws InterruptedException {
              
              
              String threadName = Thread.currentThread().getName();
              synchronized (No14){
              
              
                  System.out.println(threadName+" get NO14");
                  Thread.sleep(100);
                  synchronized (No13){
              
              
                      System.out.println(threadName+" get NO13");
                  }
              }
          }
      
          //子线程,代表peter老师
          private static class Peter extends Thread{
              
              
      
              private String name;
      
              public Peter(String name) {
              
              
                  this.name = name;
              }
      
              @Override
              public void run() {
              
              
                  Thread.currentThread().setName(name);
                  try {
              
              
                      peterDo();
                  } catch (Exception e) {
              
              
                      e.printStackTrace();
                  }
              }
          }
      
          public static void main(String[] args) throws InterruptedException {
              
              
              //主线程,代表king老师
              Thread.currentThread().setName("Peter");
              Peter peter = new Peter("King");
              peter.start();
              kingDo();
          }
      
      }
      
      
    • 两个线程互相争夺两把锁,造成了死锁,JVM中如果有大量的线程造成了死锁,会浪费大量的资源

    • Found one Java-level deadlock:
      =============================
      "King":
        waiting to lock monitor 0x000000001c663568 (object 0x000000076b9368b8, a java.lang.Object),
        which is held by "Peter"
      "Peter":
        waiting to lock monitor 0x000000001c661f68 (object 0x000000076b9368a8, a java.lang.Object),
        which is held by "King"
      
      Java stack information for the threads listed above:
      ===================================================
      "King":
              at ex10.NormalDeadLock.peterDo(NormalDeadLock.java:18)
              - waiting to lock <0x000000076b9368b8> (a java.lang.Object)
              - locked <0x000000076b9368a8> (a java.lang.Object)
              at ex10.NormalDeadLock.access$000(NormalDeadLock.java:6)
              at ex10.NormalDeadLock$Peter.run(NormalDeadLock.java:48)
      "Peter":
              at ex10.NormalDeadLock.kingDo(NormalDeadLock.java:30)
              - waiting to lock <0x000000076b9368a8> (a java.lang.Object)
              - locked <0x000000076b9368b8> (a java.lang.Object)
              at ex10.NormalDeadLock.main(NormalDeadLock.java:60)
      
      Found 1 deadlock.
      

总结

生产服务器推荐开启

  • -XX:-HeapDumpOnOutOfMemoryError 默认关闭,建议开启,在 java.lang.OutOfMemoryError 异常出现时,输出一个 dump 文件,记录当时的堆内存快照。
  • -XX:HeapDumpPath=./java_pid.hprof 用来设置堆内存快照的存储文件路径,默认是 java 进程启动位置。

调优之前开启、调优之后关闭

  • -XX:+PrintGC
    调试跟踪之打印简单的 GC 信息参数:
  • -XX:+PrintGCDetails, +XX:+PrintGCTimeStamps
    打印详细的 GC 信息
  • -Xlogger:logpath
    设置 gc 的日志路,如: -Xlogger:log/gc.log, 将 gc.log 的路径设置到当前目录的 log 目录下.
    应用场景:将 gc 的日志独立写入日志文件,将 GC 日志与系统业务日志进行了分离,方便开发人员进行追踪分析。

考虑使用

  • -XX:+PrintHeapAtGC, 打印堆信息
    参数设置: -XX:+PrintHeapAtGC
    应用场景: 获取 Heap 在每次垃圾回收前后的使用状况
  • -XX:+TraceClassLoading
    参数方法: -XX:+TraceClassLoading
    应用场景:在系统控制台信息中看到 class 加载的过程和具体的 class 信息,可用以分析类的加载顺序以及是否可进行精简操作。
  • -XX:+DisableExplicitGC 禁止在运行期显式地调用 System.gc()
    • System.gc()这个命令很耗性能,所以不要显示调用

JConsole

  • 如果linux不支持可视化的话就不用不了
    • 本地进程
      • 连接到具体的进程
    • 远程进程,如果要连接远程,需要开启JMX管理,在生产服务器不会开启,不安全

控制面板

  • 概览

    • 堆内存使用量
    • 线程使用情况
    • 类加载数量
    • cpu占用率
  • 内存

    • 图表

      • 堆内存使用量
      • 非堆内存使用量
      • Old Gen
      • Eden Space
      • Survivor Space
      • MetaSpace
      • Code Cache
      • Compressed Class Space
    • 详细信息

      • 时间
      • 已用
      • 已提交
      • 最大值
      • GC时间
  • 线程

  • 概要

  • MBean

VisualVM

  • 相比Jconsole的功能要更强大,还有各种插件,尤其是查看gc的插件,还是比较使用
  • 应用程序->具体的进程,之后进入具体进程的监控信息

控制面板

  • 概述
  • 监视
  • 线程
  • 抽样器,前面几个跟JConsole类似
  • Profiler
  • Visual GC,这是安装的插件,比较人性化,可以看到动态的内存增加过程和垃圾回收过程
    • 各个内存区域的实时使用情况
    • 线形图,各个内存区域随时间的内存变化,能在某个时间点看到具体的垃圾回收过程

Arthas

  • 官网
    • https://alibaba.github.io/arthas/

什么是Arthas

  • 运行在命令行上面的
  • 核心jar包是arthas.boot.jar
  • 阿里开源的监控诊断工具
  • 面向jvm做的aop

下载和安装

快速入门

  • java -jar arthas-boot.jar

  • 任意输入上面显示某一个进程编号后,开始自动附着到相应的进程上,启动附着成功后,进入arthas的命令行

常用命令

  • 都是小写的,记住首字母,可tab出来

  • dashboard

    • 仪表盘
    • 再输入q,退出每5秒刷新
    • Id是线程id,name是线程名,group是线程组,priority是线程优先级,state是线程状态,%CPU是cpu占比,time是运行时间,interrupt是中断状态,daemon是不是后台线程
    • memory是内存信息
    • runtime是运行时环境及参数
  • thread

    • 线程相关信息

    • -n,显示线程最忙的前几个

    • -b,显示被阻塞的具体线程,红色文字显示阻塞线程的代码位置有另一个线程在执行

    • -i,显示采样

      thread -i 1000 -n 3:每隔1000ms显示cpu占用前3名的线程

    • thread -state WAITING:显示等待状态的线程

  • jvm

    • 显示所有参数,类似jconsole

实例

  • package cn.enjoyedu.demo;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class DemoApplication {
          
          
    
        public static void main(String[] args) {
          
          
            SpringApplication.run(DemoApplication.class, args);
        }
    
    }
    
    
  • package cn.enjoyedu.demo.controller;
    
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * 类说明:
     */
    @RestController
    @RequestMapping("/btrace")
    public class DemoController {
          
          
    
        @RequestMapping("/test")
        public String test(@RequestParam("name") String name){
          
          
            return "hello,"+name;
        }
    
        @RequestMapping("/exception")
        public String exception(){
          
          
            try {
          
          
                System.out.println("start.......");
                System.out.println(1/0);
                System.out.println("end.........");
            } catch (Exception e) {
          
          
    
            }
    
            return "success";
        }
    
    }
    
    
  • 反编译,这是之前的工具不具备的功能

    • jad cn.enjoyedu.demo.controller.DemoController

      显示了写的具体类的代码,来观察代码是否更新了

  • 统计方法耗时,并且是一层一层分析的

    • trace cn.enjoyedu.demo.controller.DemoController test

      实时再访问一下这个方法,此时命令行界面就会显示具体的调用链路信息,什么开始的,哪个线程访问的,具体耗时,请求的哪个方法

  • monitor -c 5 cn.enjoyedu.demo.controller.DemoController test

    • 每5秒统计这个方法对应的执行情况
  • watch cn.enjoyedu.demo.controller.DemoController test ‘{paprams[0],returnObj}’

    • 实时再请求一下方法,就可以显示方法的入参出参
    • 会有性能损耗,相等于加了一个aop
  • stack

    • 调用路径本身
    • 加-h,就可以显示具体的用法,其余命令也是这样
  • tt

  • vmoption

    • jvm诊断相关的参数
  • sc

    • 已加载类的类信息
  • sm

    • 已加载类的方法信息
  • classloader

    • 类加载信息
  • heapdump

    • 类似于jmap的heap dump功能

猜你喜欢

转载自blog.csdn.net/Markland_l/article/details/115068809
今日推荐