VisualVM 是一个工具,它提供了一个可视界面,用于查看 Java 虚拟机 (Java Virtual Machine, JVM) 上运行的基于 Java 技术的应用程序(Java 应用程序)的详细信息。VisualVM 对 Java Development Kit (JDK) 工具所检索的 JVM 软件相关数据进行组织,并通过一种使您可以快速查看有关多个 Java 应用程序的数据的方式提供该信息。您可以查看本地应用程序以及远程主机上运行的应用程序的相关数据。此外,还可以捕获有关 JVM 软件实例的数据,并将该数据保存到本地系统,以供后期查看或与其他用户共享。

VisualVM监控远程JVM

VisualVM就是不错的监控工具,这个工具就在JAVA_HOME\bin\jvisualvm.exe

配置JVM参数

java  -Djava.rmi.server.hostname=10.10.2.138 -Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.port=18999  -Dcom.sun.management.jmxremote.ssl=false  -Dcom.sun.management.jmxremote.authenticate=false ThreadStatus

-Djava.rmi.server.hostname 配置远程主机的IP

-Dcom.sun.management.jmxremote.port 配置jmxremote使用的端口号

-Dcom.sun.management.jmxremote.authenticate=false,表示不需要鉴权,主机+端口号即可监控

启用用户认证
java \
 -Dcom.sun.management.jmxremote.authenticate=true \
 -Dcom.sun.management.jmxremote.port=18988 \
 -Dcom.sun.management.jmxremote.access.file=./jmxremote.access \
 -Dcom.sun.management.jmxremote.password.file=./jmxremote.password \
 -Dcom.sun.management.jmxremote.ssl=false \
 -Djava.rmi.server.hostname=10.10.2.138 \
 ThreadStatus

编辑./jmxremote.access权限文件

rojao readwrite

编辑./jmxremote.password密码文件

rojao 你的密码

增加访问权限

chmod 400 ./jmxremote.access
chmod 400 ./jmxremote.password

添加远程主机

在这里插入图片描述

添加JMX连接

在这里插入图片描述

线程监控

在这里插入图片描述

  • 休眠对应的sleep操作
  • 等待对应的waite
  • 驻留对应的线程池里的空闲线程
  • 监视对应的synchronized阻塞
测试
public class ThreadStatus {

    static ThreadPoolExecutor pool =
            new ThreadPoolExecutor(3,4,30,TimeUnit.SECONDS,new SynchronousQueue<>());

    public static void main(String[] args) throws InterruptedException {
        System.out.println(".......start");

        ThreadStatus status = new ThreadStatus();

        Object o = new Object();

        //休眠对应的sleep操作
        Runnable r1 = ()->{status.sync(); };
        pool.submit(r1);

        //等待对应的wait
        Runnable r2 = ()->{
            synchronized (o){
                try {
                    o.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        pool.submit(r2);

        //监视对应的synchronized阻塞
        pool.submit(r1);

        //驻留对应的线程池里的空闲线程
        Runnable r3 =()->{
            try {
                Thread.sleep(5_000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };
        pool.submit(r3);

    }

    public synchronized void sync(){
        try {
            Thread.sleep(100_000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


}

在这里插入图片描述

对应的线程栈堆信息
"pool-1-thread-4" - Thread t@17
   java.lang.Thread.State: TIMED_WAITING
	at sun.misc.Unsafe.park(Native Method)
	- parking to wait for <78667b73> (a java.util.concurrent.SynchronousQueue$TransferStack)
	at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
	at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
	at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:362)
	at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:941)
	at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1066)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)

   Locked ownable synchronizers:
	- None

"pool-1-thread-3" - Thread t@16
   java.lang.Thread.State: BLOCKED
	at ThreadStatus.sync(ThreadStatus.java:57)
	- waiting to lock <568cc6f9> (a ThreadStatus) owned by "pool-1-thread-1" t@14
	at ThreadStatus.lambda$main$0(ThreadStatus.java:23)
	at ThreadStatus$$Lambda$1/277630005.run(Unknown Source)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)

   Locked ownable synchronizers:
	- locked <27f8302d> (a java.util.concurrent.ThreadPoolExecutor$Worker)

"pool-1-thread-2" - Thread t@15
   java.lang.Thread.State: WAITING
	at java.lang.Object.wait(Native Method)
	- waiting on <75ef3e0b> (a java.lang.Object)
	at java.lang.Object.wait(Object.java:502)
	at ThreadStatus.lambda$main$1(ThreadStatus.java:30)
	at ThreadStatus$$Lambda$2/1604839423.run(Unknown Source)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)

   Locked ownable synchronizers:
	- locked <4629104a> (a java.util.concurrent.ThreadPoolExecutor$Worker)

"pool-1-thread-1" - Thread t@14
   java.lang.Thread.State: TIMED_WAITING
	at java.lang.Thread.sleep(Native Method)
	at ThreadStatus.sync(ThreadStatus.java:57)
	- locked <568cc6f9> (a ThreadStatus)
	at ThreadStatus.lambda$main$0(ThreadStatus.java:23)
	at ThreadStatus$$Lambda$1/277630005.run(Unknown Source)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)

可使用jdk自带工具jstackjstack -l [pid] > thread.dump

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐