美文网首页
JVM排查笔记

JVM排查笔记

作者: 夏天嘚花花 | 来源:发表于2019-01-17 17:04 被阅读0次

    jps

    显示指定系统内所有HotSpot虚拟机进程
    jps -l : 显示正在运行的虚拟机以及对应的pid


    image.png

    jps -v :虚拟机启动时JVM参数


    image.png

    jstat

    虚拟机统计信息监视工具,用于监视虚拟机各种运行状态信息的命名行工具。可以显示虚拟机进程中的类装载,内存,垃圾收集,JIT编译等运行参数。格式为:jstat --option --pid --interval --count
    -option: 查询的信息,可以查类装载,垃圾收集,运行编译状态三种


    image.png

    -pid : 进程ID
    -interval : 每间隔多少毫秒查询
    -count: 查询次数
    jstat -gc 11056 1000 10 : 查询进程11056每隔1秒的堆情况共查询10次


    image.png

    实例1.接下来用命令jstat -gcutil -11056 1000 10 来学习gc堆情况,-gcutil跟-gc基本一样,可查上表说明


    image.png
    E : Eden区用了78.55%空间
    S0,S1: Survivor0区用了65.38空间,Survivor1没有使用空间
    O : 老年代使用了10.21%空间
    P : 永久代(方法区)使用情况,为什么是?还不知道
    YGC : 程序运行以来一共发生了MinorGC共10次,总耗时是GCT,0.303秒

    FGC : 表示FullGC共2次,总耗时FGCT,0.206秒
    实例2.


    image.png
    image.png
    实例3.jstat -class 11056 1000 10 查询ClassLoader类加载相关信息
    image.png
    Loaded:装载的类数量
    Bytes:装载的类的总大小
    Unloaded:表示卸载类的数量
    Bytes(第二个):表示卸载类的总大小
    Time:装载类和卸载类的总时间

    实例4.jstat -gccapacity 11056 查看堆各个区域使用到的最大最小空间


    image.png

    NGCMN : 新生代最小值(KB)
    NGCMX : 新生代最大值(KB)
    NGC : 当前新生代大小(KB)
    OGCMN : 老年代最小值(KB)
    OGCMX : 老年代最大值(KB)
    PGCMN : 永久代最小值(KB)
    PGCMX : 永久代最大值(KB)

    Jinfo

    查看和修改java配置信息工具


    image.png

    查看年轻代大小


    image.png

    jmap

    用来生成堆转储快照(一般是headdump或dump文件),这个命令也可以查询finalize队列,Java堆和永久代的详细信息
    格式: jmp --option --pid


    image.png

    实例1.jmap -histo 11056 >d:\histo.txt 生成堆中对象信息(类,实例数量,合计容量)等信息


    image.png
    image.png
    实例2. jmap -dump:format=b,file=d:\11056.dump 11056
    生成11056的dump信息,这个就可以拿给可视化工具去分析
    image.png

    jhat

    搭配jmap使用,用来分析堆转储快照。一般不使用它来分析

    jstack

    可用来导出java应用程序的线程堆栈


    image.png

    实例.通过jstack来看是否发生死锁jstack -l 6772 >d:6772.txt


    image.png image.png

    通过查看导出的信息发现程序出现了死锁

    public class Test {
        private static Object locka = new Object();
        private static Object lockb = new Object();
    
        public static void main(String agrs[]) {
            Test test = new Test();
            test.deadLock();
        }
    
        private void deadLock() {
            Thread thread1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (locka){
                        try{
                            System.out.println(Thread.currentThread().getName()+" get locka ing!");
                            Thread.sleep(500);
                            System.out.println(Thread.currentThread().getName()+" after sleep 500ms!");
                        }catch(Exception e){
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName()+" need lockb!Just waiting!");
                        synchronized (lockb){
                            System.out.println(Thread.currentThread().getName()+" get lockb ing!");
                        }
                    }
                }
            },"thread1");
    
            Thread thread2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (lockb){
                        try{
                            System.out.println(Thread.currentThread().getName()+" get lockb ing!");
                            Thread.sleep(500);
                            System.out.println(Thread.currentThread().getName()+" after sleep 500ms!");
                        }catch(Exception e){
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName()+" need locka! Just waiting!");
                        synchronized (locka){
                            System.out.println(Thread.currentThread().getName()+" get locka ing!");
                        }
                    }
                }
            },"thread2");
            thread1.start();
            thread2.start();
        }
    }
    
    

    线上配置

    C_LOG_TIMESTAMP=`date '+%Y-%m-%d_%H-%M-%S'`
    
    JAVA_OPTS="$JAVA_OPTS -Djava.awt.headless=true -server -Xms50G -Xmx50G -XX:NewSize=30G -XX:MaxNewSize=30G -XX:PermSize=512m -XX:MaxPermSize=512m -Xss256k -XX:SurvivorRatio=2 -XX:NewRatio=1 -XX:+DisableExplicitGC -XX:+UseCompressedOops -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:CMSInitiatingOccupancyFraction=60 -XX:MaxDirectMemorySize=10G -XX:+CMSClassUnloadingEnabled -XX:ConcGCThreads=24 -XX:+CMSScavengeBeforeRemark -XX:+CMSParallelRemarkEnabled -XX:CMSMaxAbortablePrecleanTime=20000 -XX:+PrintTenuringDistribution"
    JAVA_OPTS="$JAVA_OPTS -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -verbose:gc -Xloggc:$CATALINA_HOME/logs/gc_$GC_LOG_TIMESTAMP.log"
    export JAVA_OPTS
    
    

    相关文章

      网友评论

          本文标题:JVM排查笔记

          本文链接:https://www.haomeiwen.com/subject/sxnidqtx.html