当前位置: 首页 > news >正文

JVMj之console Java监视与管理控制台

jconsole Java监视与管理控制台

1、jconsole介绍

jconsole (java monitoring and management console)是一款基于JMX (Java Management Extensions)

的可视化监视和管理工具。

2、启动jconsole

1、在linuxwindwos下通过jconsole启动即可。

2、然后会自动搜索本机运行的所有虚拟机进程。

3、选择其中一个进程可开始进行监控。

在这里插入图片描述

在这里插入图片描述

3、jconsole基本介绍

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

运行下面的程序,然后使用jconsole进行监控,注意设置虚拟机参数。

package com.example.controller;import java.util.ArrayList;
import java.util.List;public class Demo1 {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) {//让其一直运行着}}
}

配置启动参数:-Xms100M -XX:+UseSerialGC -XX:+PrintGCDetails

在这里插入图片描述

在这里插入图片描述

可以切换顶部的选项卡查看各种指标信息:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

内存监控

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

在这里插入图片描述

代码运行,控制台也会输出gc日志:

[GC (Allocation Failure) [DefNew: 27305K->3392K(30720K), 0.0087378 secs] 27305K->14929K(99008K), 0.0088041 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] 
[GC (Allocation Failure) [DefNew: 30720K->3369K(30720K), 0.0125603 secs] 42257K->38591K(99008K), 0.0125827 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] 
[GC (Allocation Failure) [DefNew: 30697K->3367K(30720K), 0.0206170 secs] 65919K->63766K(99008K), 0.0206669 secs] [Times: user=0.00 sys=0.02, real=0.02 secs] 
[Full GC (System.gc()) [Tenured: 60398K->66528K(68288K), 0.0339940 secs] 66709K->66528K(99008K), [Metaspace: 9255K->9255K(1058816K)], 0.0343586 secs] [Times: user=0.05 sys=0.00, real=0.04 secs] 

4、线程监控

如果上面的内存页签相当于可视化的jstat命令的话,线程页签的功能相当于可视化的jstack命令,遇到线程停顿

时可以使用这个页签进行监控分析。线程长时间停顿的主要原因主要有:等待外部资源(数据库连接、网络资源、

设备资源等)、死循环、锁等待(活锁和死锁)

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

**第一步:**运行下面的代码。

package com.example.controller;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;public class Demo2 {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() {@Overridepublic 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() {@Overridepublic void run() {while (true) {;}}}, "testBusyThread");thread.start();}/*** 线程锁等待演示*/public static void createLockThread(final Object lock) {Thread thread = new Thread(new Runnable() {@Overridepublic void run() {synchronized (lock) {try {lock.wait();} catch (InterruptedException e) {e.printStackTrace();}}}}, "testLockThread");thread.start();}
}

**第二步:**打开jconsole中查看上面程序运行情况,可以查看到3个目标线程。

在这里插入图片描述

在这里插入图片描述

**第三步:**查看目标线程信息

waitRerouceConnection线程处于读取数据状态,如下图:

在这里插入图片描述

testBusyThread线程位于代码45行,处于运行状态,如下图:

在这里插入图片描述

testLockThread处于活锁等待状态,如下图:

在这里插入图片描述

只要lock对象的notify()或notifyAll()方法被调用,这个线程便可能激活以继续执行。

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

5、线程死锁演示

**第一步:**运行下面代码:

package com.example.controller;public class Demo3 {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;}@Overridepublic 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;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +'}';}}
}

thread1持有u1的锁,thread2持有u2的锁,thread1等待获取u2的锁,thread2等待获取u1的锁,相互需要获取

的锁都被对方持有者,造成了死锁。程序中出现了死锁的情况,我们是比较难以发现的。需要依靠工具解决。刚好

jconsole就是这个美妙的工具。

**第二步:**在jconsole中打开上面程序的监控信息:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

从上面可以看出代码39行和46行处导致了死锁。

在这里插入图片描述

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

在这里插入图片描述

在这里插入图片描述

http://www.lryc.cn/news/241590.html

相关文章:

  • Android进阶知识:ANR的定位与解决
  • 基于SSM的老年公寓信息管理(有报告)。Javaee项目
  • 阿里云 ACK 新升级,打造智算时代的现代化应用平台
  • CodeWhisperer 一款好玩的 AI 插件
  • 大模型生态新篇章:以AI Agent为引,助企业创新应用落地
  • 什么是网络安全工程师,你想知道的都在这里!
  • uniapp开发的微信小程序进行代码质量控制,分包+压缩js+组件按需注入等
  • GD32替换STM32使用HAL库开发问题
  • PE文件分析
  • MySQL 中文转拼音函数
  • HTML5+CSS3+JS小实例:蜂巢里的小蜜蜂光标特效
  • leetcode做题笔记1410. HTML 实体解析器
  • sql18(Leetcode1633各赛事的用户注册率)
  • 开发旅游APP的意义
  • docker安装xxl-job
  • Django QuerySet.order_by SQL注入漏洞(CVE-2021-35042)
  • 鼠标拖拽问题,不选中文本不触发单击事件
  • Java 之 final 详解
  • 数据分析策略
  • 子虔科技亮相2023工业软件生态大会 以先进理念赋能工业软件发展
  • 《C++PrimePlus》第9章 内存模型和名称空间
  • FFmpeg常用命令讲解及实战二
  • Django之Cookie与Session,CBV加装饰器
  • 定时发朋友圈怎么发?
  • nodejs 将word转为pdf office-to-pdf
  • 12.docker的网络-host模式
  • 如何在外部数据库中存储空间化表时使用Mapinfo_mapcatalog
  • 从Github登录的双因子验证到基于时间戳的一次性密码:2FA、OTP与TOTP
  • ubuntu22.04安装wvp-gb28181-pro 2023-11-23最新版本(一键安装)
  • Spring Boot 应用的 Docker 化:从 Maven 构建到 Docker 部署的完整指南