• JVM常用参数/命令/工具


    JVM参数类型: 

    标准参数:

      -version,-help,-server,-cp

    -X参数:

      非标准参数,也就是在JDK各个版本中可能会变动

      -Xint   解释执行,-Xcomp  第一次使用就编译成本地代码,-Xmixed  混合模式,JVM自己来决定

     -XX参数:

      使用得最多的参数类型,非标准化参数,相对不稳定,主要用于JVM调优和Debug。

    • Boolean类型,格式:-XX:[+-]<name> ,+或-表示启用或者禁用name属性,比如:-XX:+UseConcMarkSweepGC  表示启用CMS类型的垃圾回收器 -XX:+UseG1GC 表示启用G1类型的垃圾回收器
    • 非Boolean类型,格式:-XX<name>=<value>表示name属性的值是value,比如:-XX:MaxGCPauseMillis=500

    其他参数:

    • -Xms1000等价于-XX:InitialHeapSize=1000
    • -Xmx1000等价于-XX:MaxHeapSize=1000
    • -Xss100等价于-XX:ThreadStackSize=100

      所以这块也相当于是-XX类型的参数

    查看参数:

      java -XX:+PrintFlagsFinal -version

     

      值得注意的是"="表示默认值,":="表示被用户或JVM修改后的值。要想查看某个进程具体参数的值,可以使用 jinfo,一般要设置参数,可以先查看一下当前参数是什么,然后进行修改。

    设置参数的方式:

    • 开发工具中设置比如IDEA,eclipse设置 VM options。
    • 运行jar包的时候:java -XX:+UseG1GC xxx.jar。
    • web容器比如tomcat,可以在脚本中的进行设置,catalina.sh。
    • 通过jinfo实时调整某个java进程的参数(参数只有被标记为manageable的flags可以被实时修改)。

      我们可以通过IDEA进行设置参数并且打印参数信息来体会一下这个过程,首先设置堆内存大小和参数打印 -Xmx100M -Xms100M -XX:+PrintFlagsFinal

       启动项目就可以看到跟上面在 CMD 窗口执行 java -XX:+PrintFlagsFinal 获取到的信息:

       查询+PrintFlagsFinal的值:

       查询堆内存大小MaxHeapSize , 注意这里的 104857600 (Byte) /1024 /1024 =100MB:

    常用参数含义:

    • -XX:CICompilerCount=3                             最大并行编译数,如果设置大于1,虽然编译速度会提高,但是同样影响系统稳定性,会增加JVM崩溃的可能
    • -XX:InitialHeapSize=100M                          初始化堆大小 简写-Xms100M
    • -XX:MaxHeapSize=100M                           最大堆大小 简写-Xm x 100M
    • -XX:NewSize=20M                                     设置年轻代的大小
    • -XX:MaxNewSize=50M                              年轻代最大大小
    • -XX:OldSize=50M                                       设置老年代大小
    • -XX:MetaspaceSize=50M                          设置方法区大小
    • -XX:MaxMetaspaceSize=50M                   方法区最大大小
    • -XX:+UseParallelGC                                  使用UseParallelGC 新生代,吞吐量优先
    • -XX:+UseParallelOldGC                             使用UseParallelOldGC 老年代,吞吐量优先
    • -XX:+UseConcMarkSweepGC                   使用CMS 老年代,停顿时间优先
    • -XX:+UseG1GC                                          使用G1GC 新生代,老年代,停顿时间优先
    • -XX:NewRatio                                             新老生代的比值,比如-XX:Ratio=4,则表示新生代:老年代=1:4,也就是新生代占整个堆内存的1/5
    • -XX:SurvivorRatio                                       两个S区和Eden区的比值,比如-XX:SurvivorRatio=8,也就是(S0+S1):Eden=2:8,也就是一个S占整个新生代的1/10
    • -XX:+HeapDumpOnOutOfMemoryError      启动堆内存溢出打印当JVM堆内存发生溢出时,也就是OOM,自动生成dump文件
    • -XX:HeapDumpPath=heap.hprof                指定堆内存溢出打印目录 表示在当前目录生成一个heap.hprof文件
    • XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:$CATALINA_HOME/logs/gc.log   :打印出GC日志 可以使用不同的垃圾收集器,对比查看GC情况
    • -Xss128k                                                    设置每个线程的堆栈大小 经验值是3000-5000最佳
    • -XX:MaxTenuringThreshold=6                   提升年老代的最大临界值 默认值为 15
    • -XX:InitiatingHeapOccupancyPercent       启动并发GC周期时堆内存使用占比G1之类的垃圾收集器用它来触发并发GC周期,基于整个堆的使用率,而不只是某一代内存的使用比. 值为 0 则表示”一直执行GC循环”. 默认值为 45.
    • -XX:G1HeapWastePercent                       允许的浪费堆空间的占比默认是10%,如果并发标记可回收的空间小于10%,则不会触发MixedGC。
    • -XX:MaxGCPauseMillis=200ms                G1最大停顿时间暂停时间不能太小,太小的话就会导致出现G1跟不上垃圾产生的速度。最终退化成Full GC。所以对这个参数的调优是一个持续的过程,逐步调整到最佳状态。
    • -XX:ConcGCThreads=n                            并发垃圾收集器使用的线程数量 默认值随JVM运行的平台不同而不同
    • -XX:G1MixedGCLiveThresholdPercent=65   混合垃圾回收周期中要包括的旧区域设置占用率阈值  默认占用率为 65%
    • -XX:G1MixedGCCountTarget=8                设置标记周期完成后,对存活数据上限为 G1MixedGCLIveThresholdPercent 的旧区域执行混合垃圾回收的目标次数默认8次混合垃圾回收,混合回收的目标是要控制在此目标次数以内
    • -XX:G1OldCSetRegionThresholdPercent=1   描述Mixed GC时,Old Region被加入到CSet中默认情况下,G1只把10%的Old Region加入到CSet中

    常用命令:

    jps :

      查看java进程:

    jinfo :

      实时查看和调整JVM配置参数 jinfo -flag name PID 查看某个java进程的 name属性的值

      jinfo -flag MaxHeapSize PID :如下图显示最大堆大小

      jinfo -flag UseG1GC PID :如下图未使用G1GC

       参数只有被标记为manageable的 flags 可以被实时修改,jinfo -flag [+|-] PID:

      jinfo -flag [+|-]name pid   描述:开启或者关闭对应名称的参数

      查看曾经赋过值的一些参数 jinfo -flags PID

    jstat :

      查看虚拟机性能统计信息,查看类装载信息,jstat -class PID 1000 10   查看某个java进程的类装载信息,每1000毫秒输出一次,共输出10次

       查看垃圾收集信息 jstat -gc PID 1000 10

    jstack:

      查看线程堆栈信息 ,jstack PID

       排查死锁案例 DeadLockDemo:

    public class DeadLockDemo {
        public static void main(String[] args) {
            DeadLock d1 = new DeadLock(true);
            DeadLock d2 = new DeadLock(false);
            Thread t1 = new Thread(d1);
            Thread t2 = new Thread(d2);
            t1.start();
            t2.start();
        }
    }
    
    //定义锁对象
    class MyLock {
        public static Object obj1 = new Object();
        public static Object obj2 = new Object();
    }
    
    //死锁代码
    class DeadLock implements Runnable {
        private boolean flag;
    
        DeadLock(boolean flag) {
            this.flag = flag;
        }
    
        public void run() {
            if (flag) {
                while (true) {
                    synchronized (MyLock.obj1) {
                        System.out.println(Thread.currentThread().getName() + "----if 获得obj1锁");
                        synchronized (MyLock.obj2) {
                            System.out.println(Thread.currentThread().getName() + "--- -if获得obj2锁");
                        }
                    }
                }
            } else {
                while (true) {
                    synchronized (MyLock.obj2) {
                        System.out.println(Thread.currentThread().getName() + "----否则 获得obj2锁");
                        synchronized (MyLock.obj1) {
                            System.out.println(Thread.currentThread().getName() + "--- -否则获得obj1锁");
                        }
                    }
                }
            }
        }
    }

      运行结果:

       jps 查看进程并且打印栈信息:

       将打印的信息拉到最下面会发现死锁的信息:

    jmap:

      生成堆转储快照,打印出堆内存相关信息,先设置虚拟机参数:-XX:+PrintFlagsFinal -Xms300M -Xmx300M,然后启动。

      dump出堆内存相关信息:jmap -dump:format=b,file=heap.hprof PID  。要是在发生堆内存溢出的时候,能自动dump出该文件就好了一般在开发中,JVM参数可以加上下面两句,这样内存溢出时,会自动dump出该文件,设置 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heap.hprof 即可在OOM的时候dump出该文件。关于dump下来的文件,一般dump下来的文件可以结合工具来分析。

    常用工具:

      参数也了解了,命令也知道了,关键是用起来不是很方便,要是有图形化的界面就好了。一定会有好事之者来做这件事情。

    jconsole:

      JConsole工具是JDK自带的可视化监控工具。查看java应用程序的运行概况、监控堆信息、永久区使用情况、类加载情况等。在${JAVA+HOME}/bin下面找到并打开

    jvisualvm:

      在${JAVA+HOME}/bin下面找到并打开,监控本地Java进程:可以监控本地的java进程的CPU,类,线程等

     

      监控远端Java进程:比如监控远端tomcat,部署在阿里云服务器上的tomcat

      在visualvm中选中“远程”,右击“添加”

      主机名上写服务器的ip地址,比如192.168.1.101,然后点击“确定”

      右击该主机“192.168.1.101”,添加“JMX”[也就是通过JMX技术具体监控远端服务器哪个Java进程]

      要想让服务器上的tomcat被连接,需要改一下 bin/catalina.sh 这个文件.注意下面的8998不要和服务器上其他端口冲突:

    JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote -Djava.rmi.server.hostname=192.168.1.101 -Dcom.sun.management.jmxremote.port=8998 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=true -Dcom.sun.ma
    nagement.jmxremote.access.file=../conf/jmxremote.access -Dcom.sun.management.jmxremote.password.file=../conf/jmxremote.password"

      在 ../conf 文件中添加两个文件jmxremote.access和jmxremote.password,jmxremote.access 文件:

    guest readonly
    manager readwrite

      jmxremote.password 文件:

    guest guest
    manager manager

      授予权限 : chmod 600 *jmxremot*

    Arthas :

      github :https://github.com/alibaba/arthas 。Arthas 是Alibaba开源的Java诊断工具,采用命令行交互模式,是排查jvm相关问题的利器。Arthas 是Alibaba开源的Java诊断工具,深受开发者喜爱。当你遇到以下类似问题而束手无策时,Arthas 可以帮助你解决:

    • 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
    • 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
    • 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
    • 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
    • 是否有一个全局视角来查看系统的运行状况?
    • 有什么办法可以监控到JVM的实时运行状态?

      Arthas 支持JDK 6+,支持Linux/Mac/Windows,采用命令行交互模式,同时提供丰富的 Tab 自动补全功能,进一步方便进行问题的定位和诊断。

      下载安装
    curl -O https://alibaba.github.io/arthas/arthas-boot.jar
    java -jar arthas-boot.jar
    # 然后可以选择一个Java进程

       启动后选择对应的Java进程:

      Print usage :java -jar arthas-boot.jar -h .

      常用命令:具体每个命令怎么使用,大家可以自己查阅资料

    version:查看arthas版本号
    help:查看命名帮助信息
    cls:清空屏幕
    session:查看当前会话信息
    quit:退出arthas客户端
    ---
    dashboard:当前进程的实时数据面板
    thread:当前JVM的线程堆栈信息
    jvm:查看当前JVM的信息
    sysprop:查看JVM的系统属性
    ---
    sc:查看JVM已经加载的类信息
    dump:dump已经加载类的byte code到特定目录
    jad:反编译指定已加载类的源码
    ---
    monitor:方法执行监控
    watch:方法执行数据观测
    trace:方法内部调用路径,并输出方法路径上的每个节点上耗时
    stack:输出当前方法被调用的调用路径
    ......

    MAT:

      Dump信息包含的内容

    • All Objects:Class, fields, primitive values and references
    • All Classes:Classloader, name, super class, static fields
    • Garbage Collection Roots:Objects defined to be reachable by the JVM
    • Thread Stacks and Local Variables:The call-stacks of threads at the moment of the snapshot, and per-frame information about local objects

      获取Dump文件

    @RestController
    public class HeapController {
      List<Person> list=new ArrayList<Person>();
      @GetMapping("/heap")
      public String heap() throws Exception{
        while(true){
          list.add(new Person());
          Thread.sleep(1);
       }
     }
    }

      启动springboot,访问上面这个接口造成内存溢出。

    • 手动:jmap -dump:format=b,file=heap.hprof PID
    • 自动:-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heap.hprof

      使用:

      Histogram:Histogram可以列出内存中的对象,对象的个数及其大小,Class Name:类名称,java类名,Objects:类的对象的数量,这个对象被创建了多少个,Shallow Heap:一个对象内存的消耗大小,不包含对其他对象的引用,Retained Heap:是shallow Heap的总和,即该对象被GC之后所能回收到内存的总和

      右击类名--->List Objects--->with incoming references--->列出该类的实例。右击Java对象名--->Merge Shortest Paths to GC Roots--->exclude all ...--->找到GCRoot以及原因。如下图我们会发现EntityDemo这个类得实例有10W多个。

     

      Leak Suspects:查找并分析内存泄漏的可能原因Reports--->Leak Suspects--->Details

     

       他就会告诉我们哪里存在问题,然后我们就可以粗略定位到问题,然后去看代码就能定位到。以上就是关于JVM得内存信息得获取及分析得一些简单介绍。

  • 相关阅读:
    min.js文件 反压缩查看
    Simple HTML DOM解析器 使用php解析网页字符串进行dom操作
    使用clipboard.js实现页面内容复制到剪贴板
    php7微信支付回调失败
    微信卡券开发
    Windows内存性能分析(一)内存泄漏
    LoadRunner添加检查点
    LoadRunner中两种录制模式的区别
    Jmeter参数化_CSV Data Set Config
    APTM敏捷性能测试模型
  • 原文地址:https://www.cnblogs.com/wuzhenzhao/p/12469403.html
Copyright © 2020-2023  润新知