关于JVM案例分析

Posted zjoe80

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于JVM案例分析相关的知识,希望对你有一定的参考价值。

线程分析篇

Java 语言能够很好的实现多线程应用程序。当对一个多线程应用程序进行调试或者开发后期做性能调优的时候,往往需要了解当前程序中所有线程的运行状态,是否有死锁、热锁等情况的发生,从而分析系统可能存在的问题。

在 VisualVM 的监视标签内,可以查看当前应用程序中所有活动线程(Live threads)和守护线程(Daemon threads)的数量等实时信息。

 

运行一段小程序,代码如下:

技术图片
package jvisualVM;

public class MyThread extends Thread{
    
    public static void main(String[] args) {
        
        MyThread mt1 = new MyThread("Thread a");
        MyThread mt2 = new MyThread("Thread b");
        
        mt1.setName("My-Thread-1 ");
        mt2.setName("My-Thread-2 ");
        
        mt1.start();
        mt2.start();
    }
    
    public MyThread(String name) {
    }

    public void run() {
        
        while (true) {
            
        }
    }
    

}
技术图片

 

Live threads 从11增加两个 变成13了

Daemon threads从8增加两个 变成10了 

技术图片

 

VisualVM 的线程标签提供了三种视图,默认会以时间线的方式展现, 如下图:

可以看到两个我们run的程序里启的线程:My-Thread-1 和 My-Thread-2

技术图片

 

另外还有两种视图分别是表视图和详细信息视图, 这里看一下每个Thread的详细视图:

技术图片

 

再来一段死锁的程序,看VisualVM 能否分析出来

技术图片
package jvisualVM;

public class DeadLock {
    public static void main(String[] args) {
        Resource r1 = new Resource();
        Resource r0 = new Resource();

        Thread myTh1 = new LockThread1(r1, r0);
        Thread myTh0 = new LockThread0(r1, r0);

        myTh1.setName("DeadLock-1 ");
        myTh0.setName("DeadLock-0 ");

        myTh1.start();
        myTh0.start();
    }
}

    class Resource {
        private int i;
    
        public int getI() {
            return i;
        }
    
        public void setI(int i) {
            this.i = i;
        }
        
    }

    class LockThread1 extends Thread {
        private Resource r1, r2;
    
        public LockThread1(Resource r1, Resource r2) {
            this.r1 = r1;
            this.r2 = r2;
        }
    
        @Override
        public void run() {
            int j = 0;
            while (true) {
                synchronized (r1) {
                    System.out.println("The first thread got r1‘s lock " + j);
                    synchronized (r2) {
                        System.out.println("The first thread got r2‘s lock  " + j);
                    }
                }
                j++;
            }
        }
    
    }

    class LockThread0 extends Thread {
        private Resource r1, r2;
    
        public LockThread0(Resource r1, Resource r2) {
            this.r1 = r1;
            this.r2 = r2;
        }
    
        @Override
        public void run() {
            int j = 0;
            while (true) {
                synchronized (r2) {
                    System.out.println("The second thread got r2‘s lock  " + j);
                    synchronized (r1) {
                        System.out.println("The second thread got r1‘s lock" + j);
                    }
                }
                j++;
            }
        }
    
    }
技术图片

 

打开VisualVM检测到的JVM进程,我们可以看到这个tab在闪,VisualVM已经检测到我这个package下面的DeadLock类出错了

切换到Thread tab, 可以看到死锁了, Deadlock detected!

另外可以点击Thread Dump 线程转储,进一步分析,在这里就不赘述了,有兴趣的读者可以自行实验。

 技术图片

 

以上是关于关于JVM案例分析的主要内容,如果未能解决你的问题,请参考以下文章

关于JVM案例分析

关于JVM案例分析

java 简单的代码片段,展示如何将javaagent附加到运行JVM进程

从JVM的角度看JAVA代码--代码优化

关于JVM案例分析

JVM理论:(三/7)关于类变量成员变量局部变量的案例总结