[JDK工具-9] jconsole Java监视与管理控制台

[JDK工具-9] jconsole Java监视与管理控制台javaJDK 工具 jconsoleJava 监视与管理控制台 jconsole

大家好,欢迎来到IT知识分享网。

在这里插入图片描述

JConsole(java monitoring and management console)

1. 介绍

位置:jdk\bin

使用:双击exe文件打开控制台

作用:JConsole是一款基于JMX的可视化监视和管理工具。

JMX,即Java管理扩展(Java Management Extensions),是一种用于管理和监控Java应用程序与系统资源的技术。它允许开发人员和管理员以标准化的方式访问和操作应用程序内部的状态信息、配置参数、统计指标等,从而实现对应用程序的监控、配置和管理功能。

JConsole 基本包括以下基本功能:概述、内存、线程、类、VM概要、MBean

2. 内存监控

运行下面的程序、然后使用JConsole进行监控;注意设置虚拟机参数

public class JConsoleDemo { 
    static class OOMObject { 
    public byte[] placeholder = new byte[64 * 1024]; } public static void fillHeap(int num) throws InterruptedException { 
    Thread.sleep(20000); // 先运行程序,在执行监控 List<OOMObject> list = new ArrayList<OOMObject>(); for (int i = 0; i < num; i++) { 
    // 稍作延时,令监视曲线的变化更加明显 Thread.sleep(50); list.add(new OOMObject()); } System.gc(); } public static void main(String[] args) throws Exception { 
    fillHeap(1000); while (true) { 
    //让其一直运行着 } } } 

“内存”页签相当于可视化的jstat 命令,用于监视受收集器管理的虚拟机内存的变换趋势。

在这里插入图片描述
在这里插入图片描述

3. 线程监控

如果上面的“内存”页签相当于可视化的jstat命令的话,“线程”页签的功能相当于可视化的jstack命令,遇到线程停顿时可以使用这个页签进行监控分析。线程长时间停顿的主要原因主要有:等待外部资源(数据库连接、网络资源、设备资源等)、死循环、锁等待(活锁和死锁)

下面三个方法分别等待控制台输入、死循环演示、线程锁等待演示

  • 第一步:运行如下代码:
package com.xin.demo.threaddemo.bookdemo; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class JConsoleDemo1 { 
    public static void main(String[] args) throws IOException { 
    waitRerouceConnection(); createBusyThread(); createLockThread(new Object()); } / * 等待控制台输入 * * @throws IOException */ public static void waitRerouceConnection() throws IOException { 
    Thread thread = new Thread(new Runnable() { 
    @Override public void run() { 
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); try { 
    br.readLine(); } catch (IOException e) { 
    e.printStackTrace(); } } }, "waitRerouceConnection"); thread.start(); } / * 线程死循环演示 */ public static void createBusyThread() { 
    Thread thread = new Thread(new Runnable() { 
    @Override public void run() { 
    while (true) { 
    } } }, "testBusyThread"); thread.start(); } / * 线程锁等待演示 */ public static void createLockThread(final Object lock) { 
    Thread thread = new Thread(new Runnable() { 
    @Override public void run() { 
    synchronized (lock) { 
    try { 
    lock.wait(); } catch (InterruptedException e) { 
    e.printStackTrace(); } } } }, "testLockThread"); thread.start(); } } 
  • 第二步:打开jconsole中查看上面程序运行情况,可以查看到3个目标线程
  • 第三步:查看目标线程信息
    • waitRerouceConnection线程处于读取数据状态,如下图:
      在这里插入图片描述
    • testBusyThread线程位于代码39行,处于运行状态,如下图:
      在这里插入图片描述
    • testLockThread处于活锁等待状态,如下图:
      在这里插入图片描述
      只要lock对象的notify()或notifyAll()方法被调用,这个线程便可能激活以继续执行

通过“线程”这个窗口可以很方便查询虚拟机中的线程堆栈信息,对发现系统中的一些问题非常有帮助。

4. 线程死锁演示

  • 第一步:运行下面代码:
package com.xin.demo.threaddemo.bookdemo; public class JConsoleDemo2 { 
    public static void main(String[] args) { 
    User u1 = new User("u1"); User u2 = new User("u2"); Thread thread1 = new Thread(new SynAddRunalbe(u1, u2, 1, 2, true)); thread1.setName("thread1"); thread1.start(); Thread thread2 = new Thread(new SynAddRunalbe(u1, u2, 2, 1, false)); thread2.setName("thread2"); thread2.start(); } / * 线程死锁等待演示 */ public static class SynAddRunalbe implements Runnable { 
    User u1, u2; int a, b; boolean flag; public SynAddRunalbe(User u1, User u2, int a, int b, boolean flag) { 
    this.u1 = u1; this.u2 = u2; this.a = a; this.b = b; this.flag = flag; } @Override public void run() { 
    try { 
    if (flag) { 
    synchronized (u1) { 
    Thread.sleep(100); synchronized (u2) { 
    System.out.println(a + b); } } } else { 
    synchronized (u2) { 
    Thread.sleep(100); synchronized (u1) { 
    System.out.println(a + b); } } } } catch (InterruptedException e) { 
    e.printStackTrace(); } } } public static class User { 
    private String name; public String getName() { 
    return name; } public void setName(String name) { 
    this.name = name; } public User(String name) { 
    this.name = name; } @Override public String toString() { 
    return "User{" + "name='" + name + '\'' + '}'; } } } 

thread1持有u1的锁,thread2持有u2的锁,thread1等待获取u2的锁,thread2等待获取u1的锁,相互需要获取的锁都被对方持有者,造成了死锁。程序中出现了死锁的情况,我们是比较难以发现的。需要依靠工具解决。刚好jconsole就是这个美妙的工具。

  • 第二步:在jconsole中打开上面程序的监控信息:
    在这里插入图片描述
    在这里插入图片描述
    从上面可以看出代码42行和35行处导致了死锁。


- [x]
关于程序死锁的,我们还可以使用命令行工具jstack来查看java线程堆栈信息,也可以发现死锁。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/120599.html

(0)
上一篇 2025-10-28 18:10
下一篇 2025-10-28 18:20

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信