虚拟机性能监控与故障处理工具

虚拟机性能监控与故障处理工具

Java与C++之间有一堵内存动态分配和垃圾收集技术所围成的“高墙”,墙外面的人想进去,墙里面的人想出来。

本文内容基本来自于《深入理解Java虚拟机-JVM高级特性与最佳实践》第4章,是对这本书学习的笔记

概述

理论总是作为指导实践的工具,能把这些知识应用到实际工作中才是我们的最终目的。给系统定位问题的时候,知识、经验是关键基础,数据是依据,工具是运用知识处理数据的手段。

JDK的命令行工具

1 jps:虚拟机进程状况工具

JVM Process Status Tool,显示指定系统内所有的HotSpot虚拟机进程。(从名字和功能都与UNIX的ps类似)

2 jstat:虚拟机统计信息监视工具

JVM Statistics Monitoring Tool,用于收集HotSpot虚拟机进程。

3 jinfo:Java配置信息工具

Configuration Info for Java,显示虚拟机配置信息。

4 jmap:Java内存映像工具

Memory Map for Java,生成虚拟机的内存转储快照(heapdump文件)。

5 jhat:虚拟机堆转储快照分析工具

JVM Heap Dump Browser,用于分析heapdump文件,它会建立一个HTTP/HTML服务器,让用户可以在浏览器上查看分析结果。

6 jstack:Java堆栈跟踪工具

Stack Trace for Java,显示虚拟机的线程快照。

7 HSDIS:JIT生成代码反汇编

当我们分析程序的执行语义问题(虚拟机作了什么)时,在字节码层面上分析完全可行,但在分析程序的执行行为问题(虚拟机时怎样做的、性能如何)时,由于JIT编译器的存在,在字节马层面上分析就没有什么意义了,需要通过其他方式解决。
HSDIS是一个Sun官方推荐的HotSpot虚拟机JIT编译代码的反汇编插件,它包含在HotSpot虚拟机的源码之中,但没有提供编译后的程序。《深入理解Java虚拟机》(第二版,2013.6)这本书说可以在下面网站中下载到单独的源码:
http://kenai.com/projects/base-hsdis
但现在这网站似乎已经被关闭了。可以自己找类似下面的资料试一下:
https://blog.csdn.net/VimGuy/article/details/81879210

在这里插入图片描述

HSDIS的作用是让Hotpot的-XX:+PrintAssembly指令调用它来把动态生成的本地代码还原为汇编代码输出,同时还生成了大量非常有价值的注释,这样我们就可以通过输出的代码来分析问题。

JDK的可视化工具

JConsole:Java监视与管理控制台

1 启动JConsole

打开$JAVA_HOME/bin/jconsole即可。
概述页签显示整个虚拟机主要运行数据的概览,其中包括“堆内存使用情况”、“线程”、“类”、“CPU使用情况”4中信息的曲线图。
在这里插入图片描述

2 内存监控

相当于可视化的jstat命令,用于监视收集器管理的虚拟机内存(Java堆和永久代)的变化趋势。
下面是示例代码和监视效果,可以从中体会关于内存的基础知识:

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

public class MemoryListenTest {

	static class OOMObject{
		public byte[] placeHolder = new byte[64 * 1024];
	}
	
	public static void fillHeap(int num) throws InterruptedException{
		List<OOMObject> list =new ArrayList<OOMObject>();
		for(int i = 0; i < num; i++) {
			Thread.sleep(50);
			list.add(new OOMObject());
		}
//		System.gc();
	}
	
	
	/**
	 * VM args:-Xms100m -Xmx100m -XX:+UseSerialGC
	 * @param args
	 * @throws InterruptedException
	 */
	public static void main(String[] args) throws InterruptedException {
		System.out.println("start");
		Thread.sleep(10 * 1000);
		fillHeap(1000);
		System.gc();
		System.out.println("end");
		Thread.sleep(100 * 1000);
	}
}

在这里插入图片描述

3 线程监控

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

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class ThreadListenTest {
	/**
	 * 线程死循环演示
	 */
	public static void createBusyThread() {
		new Thread(() -> {
			while (true) {
				;
			}
		}, "testBusyThread").start();
	}

	/**
	 * 线程锁等待演示
	 */
	public static void createLockThread(final Object lock) {
		new Thread(() -> {
			synchronized (lock) {
				try {
					lock.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}, "testLockThread").start();
	}
	
	public static void main(String[] args) throws IOException {
		BufferedReader br =new BufferedReader(new InputStreamReader(System.in));
		br.readLine();
		createBusyThread();
		br.readLine();
		Object obj = new Object();
		createLockThread(obj);
	}
}

可以在Jconsole中查看到main、testBusyThread、testLockThread线程的状态。
在这里插入图片描述

死锁示例如下:

public class DeadLockTreadTest {
	/**
	 * 线程死锁等待演示
	 */
	static class SynAddRunnable implements Runnable{
		int a, b;
		public SynAddRunnable(int a, int b) {
			this.a = a;
			this.b = b;
		}
		
		@Override
		public void run() {
			synchronized (Integer.valueOf(a)) {
				synchronized ( Integer.valueOf(b)) {
					System.out.println(a + b);
				}
			}
		}
		
		public static void main(String[] args) {
			for(int i = 0; i < 100; i++) {
				new Thread(new SynAddRunnable(1,  2)).start();
				new Thread(new SynAddRunnable(2, 1)).start();
			}
		}
	}
}

下图为点击监测死锁后的页面,Thread-15与Thread12形成死锁:
在这里插入图片描述

VisualVM:多合一故障处理工具

VisualVM(All-inOne Java Troubleshooting Tool)时到目前(2013.6)为止随JDK发布的功能最强大的运行监视和故障处理程序,官方在软件说明中写上了“All-in-One”的描述字样,预示着它除了运行监视、故障处理外,还提供了很多其他方面的功能,如性能分析(Profiling)。
打开${JAVA_HOME}/bin/jvisualvm即可使用这一工具。
详见:https://visualvm.github.io/gettingstarted.html?Java_VisualVM

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值