可视化虚拟机工具VisualVM和Jconsole

目录

开篇介绍:

 一、本地Jconsole远程连接阿里云服务

 二、先看本地Jconsole内存监控验证

 三、再看本地Jconsole线程验证

 四、idea -VisualVM插件安装


开篇介绍:

         生产环境中直接排查JVM的话,使用适当的虚拟机监控和分析的工具可以加快我们分析数据、定位解决问题的速度。本博文重点介绍Jconsole和VisualVM工具的使用。

一、本地Jconsole远程连接阿里云服务

先配置环境变量:

export JAVA_OPTS='-Djava.rmi.server.hostname=112.74.xxxx.xxx -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=7777 -Dcom.sun.management.jmxremote.rmi.port=7777 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false'
 

配置介绍:

hostname 阿里云公网IP

jmxremote.port和rmi.port 连接时候所使用的端口号,自定义。阿里云的话记得在安全组中开放这个。

配置好后,source /etc/profile 立即让配置生效

然后启动jar包

 在本地cmd中输入jconsole,在弹出来的控制台上填写远程进程信息:

 二、先看本地Jconsole内存监控验证

启动程序main,并连接上服务

package com.wnn.jvm;

import java.util.ArrayList;
import java.util.List;

public class JconsoleMemory {

    public byte[] b1 = new byte[1024*512];

    public static void main(String[] args) throws InterruptedException {
        System.out.println("main thread start");
        Thread.sleep(10000);
        allocate(10000);
    }

    private static void allocate(int n) {
        List<JconsoleMemory> jconsoleMemoryList = new ArrayList<>();

        for (int i = 0; i < n; i++) {
            try {
               Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            jconsoleMemoryList.add(new JconsoleMemory());
        }
    }
}

看看堆内存的使用 随着时间加大,堆使用量持续增长,因为循环过程中一直在堆中创建对象在方法体中有引用,无法回收,一直增大

老年代也在不断增长 

Eden区 占满的时候会发生复制 ,所以增长会呈现折现的方式 

持续增加下,就发生Java heap space

java.lang.OutOfMemoryError: Java heap space 堆溢出 错误的原因, 很多时候, 就类似于将 XXL 号的对象,往 S 号的 Java heap space 里面塞 

 

 三、再看本地Jconsole线程验证

线程状态waiting、timeWaiting 死锁情况的模拟

package com.wnn.jvm;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import javax.annotation.PostConstruct;

@SpringBootApplication
@EnableAutoConfiguration
public class DemoApplication {


	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}

	private static  Object lock1 = new Object();
	private static  Object lock2 = new Object();

	class WaitCondition{
		boolean isOpen = false;
		public  void setOpen(){
			isOpen = true;
		}
	}

	WaitCondition waitCondition = new WaitCondition();


	/**
	 * 在springboot项目启动的时候所执行的方法
	 * 在bean加载完但用户线程进来之前执行的方法
	 */

	@PostConstruct
	public void deadLock(){
		new Thread(()->{
			synchronized (lock1){
				try {
					System.out.println(Thread.currentThread().getName()+"得到Lock1");
					Thread.sleep(3000L);
				}catch (Exception e){
					e.printStackTrace();
				}
				synchronized (lock2){
					System.out.println(Thread.currentThread().getName()+"得到Lock2");
				}
			}
		},"线程1").start();


		new Thread(()->{
			synchronized (lock2){
				try {
					System.out.println(Thread.currentThread().getName()+"得到Lock2");
					Thread.sleep(3000L);
				}catch (Exception e){
					e.printStackTrace();
				}
				synchronized (lock1){
					System.out.println(Thread.currentThread().getName()+"得到Lock1");
				}
			}
		},"线程2").start();

		new Thread(()->{
			synchronized (waitCondition){
				while (!waitCondition.isOpen){
					try {
						waitCondition.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		},"线程3").start();


		new Thread(()->{
			synchronized (waitCondition){
				while (!waitCondition.isOpen){
					try {
						waitCondition.wait(1000000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		},"线程4").start();


	}


}

线程一,二是死锁的状态

 WAITING 一个正在无限期等待另一个线程执行一个特别的动作的线程处于这一状态:

  TIMED_WAITING 一个正在限时等待另一个线程执行一个动作的线程处于这一状态:

 Blocked状态与Waiting状态的区别:

WAITING 状态属于主动地显式地申请的阻塞,BLOCKED 则属于被动的阻塞

四、idea -VisualVM插件安装

VisualVM是什么?

        VisualVM是一个集成命令行JDK工具和轻量级分析功能的可视化工具

第一步:在IDEA安装VisualVM插件,File-> Setting-> Plugins -> Browers Repositrories 搜索VisualVM Launcher安装并重启IDEA

 第二步:点击配置VisualVM executable执行路径

 idea右侧上方多了2个按钮:

 然后正常启动程序,会发现 有个弹窗出来了

 运行段错误代码,然后堆dump下,再看看耗费的实例数:

@PostConstruct
	public void visualVM() throws InterruptedException{
		Map<Integer,Integer> map = new HashMap<>();
		int i = 0;
		for (int j = 0; j < 1000; j++) {
			Thread.sleep(10000);
			while (i<2000000){
				i++;
				try{
					map.put(i,i);
				}catch (OutOfMemoryError e){
					e.printStackTrace();
					break;
				}
			}
		}
	}

 可以通过这种方式来看实际运行服务中具体是哪个对象占用的实例数很大。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值