目录

  • 一、简介
  • 二、内存分析
    • 1、Heap堆
  • 三、CPU分析
  • 四、线程分析

一、简介

VisualVM 是一款免费的,集成了多个JDK命令行工具的可视化工具,它能为您提供强大的分析能力,对Java应用程序做 性能分析和调优 。这些功能包括 生成和分析海量数据跟踪内存泄漏监控垃圾回收器执行内存和CPU分析。本文主要介绍如何使用VisualVM进行性能分析及调优。

自从JDK 6 Update 7 以后已经作为Oracle JDK的一部分,位于JDK根目录的bin文件夹下,无需安装,直接运行即可。

JDK路径查看:

  • MAC查找JDK的路径

  • Windows查找JDK的路径

二、内存分析

VisualVM通过检测JVM中加载的类和对象信息等帮助我们分析内存使用情况,我们可以通过VisualVM的监视标签对应用程序进行内存分析。

1、Heap堆

首先写一个内存堆占用较大的例子,代码如下:

public class Main {public final static int OUTOFMEMORY = 200000000;public static String oom;public static StringBuffer tempOOM = new StringBuffer();public static void main(String[] args){threadHeap(OUTOFMEMORY);}public static void threadHeap(final int len){Thread t = new Thread(new Runnable() {@Overridepublic void run() {int i = 0;while(i < len){i++;try{tempOOM.append("abcdefghijabcdefghijabcdefghijabcdefghijabcdefghij");if(i%1000 == 1){Thread.sleep(10);}//Thread.sleep(1);} catch (Exception e){e.printStackTrace();break;} catch (Error e){e.printStackTrace();break;}}oom = tempOOM.toString();System.out.println("Thread Heap Length : " + oom.length());}});t.setName("ThreadHeap_1");t.start();}
}

运行该段代码,然后查看VisualVM Monitor(监视), 堆内存会慢慢变大。


在程序运行结束之前, 点击 堆Dump 按钮, 等待一会儿,得到dump结果,可以看到一些摘要信息。

点击类, 发现char[]所占用的内存是最大的。

双击 char[] ,得到如下实例数结果。

StringBuffer类型的全局变量 tempOOM 占用内存特别大, 注意局部变量是无法通过堆dump来得到分析结果的

另外,对于 堆 dump 来说,在远程监控jvm的时候,VisualVM是没有这个功能的,只有本地监控的时候才有

三、CPU分析

CPU 性能分析的主要目的是统计函数的调用情况及执行时间,或者更简单的情况就是统计应用程序的 CPU 使用情况。

没有程序运行时的 CPU 使用情况如下图:

运行一段 占用CPU 的小程序,代码如下:

public class Main {public static void main(String[] args){cpuFix();}public static void cpuFix(){try{// 80%的占有率int busyTime = 8;// 20%的占有率int idelTime = 2;// 开始时间long startTime = 0;while (true) {// 开始时间startTime = System.currentTimeMillis();/** 运行时间*/while (System.currentTimeMillis() - startTime < busyTime) {;}// 休息时间Thread.sleep(idelTime);}}catch(Exception ex){ex.printStackTrace();}}
}

结果如下:

过高的 CPU 使用率可能是由于我们的项目中存在低效的代码;

在我们对程序施压的时候,过低的 CPU 使用率也有可能是程序的问题。

点击【抽样器】, 点击【CPU】按钮, 启动CPU性能分析会话,VisualVM 会检测应用程序所有的被调用的方法,在【CPU 样例】下可以看到我们的方法cpuFix() 的自用时间最长, 如下图:

切换到【线程 CPU 时间】页面下,我们的 main 函数这个进程占用CPU时间最长, 如下图:

四、线程分析

Java 语言能够很好的实现多线程应用程序。当我们对一个多线程应用程序进行调试或者开发后期做性能调优的时候,往往需要了解当前程序中所有线程的运行状态,是否有死锁、热锁等情况的发生,从而分析系统可能存在的问题。

在 VisualVM 的监视标签内,我们可以查看当前应用程序中所有实时线程(Live threads)和守护线程(Daemon threads)的数量等实时信息。

运行一段小程序,代码如下:

public class Main {public static void main(String[] args){startThread("Thread_1");startThread("Thread_2");}public static void startThread(String threadName){Thread thread = new Thread(new Runnable() {@Overridepublic void run() {while (true){}}});thread.setName(threadName);thread.start();}
}


VisualVM 的线程标签提供了三种视图,默认会以时间线的方式展现, 如下图:

可以看到两个我们run的程序里启的线程:Thread_1 和 Thread_2。


再来一段死锁的程序,看VisualVM 能否分析出来:

public class Main {public static void main(String[] args){diethread();}public static void diethread(){DieThread d1=new DieThread(true);DieThread d2=new DieThread(false);final Thread t1 = new Thread(d1);final Thread t2 = new Thread(d2);t1.setName("DieThread_1");t2.setName("DieThread_2");t1.start();t2.start();}
}package com.javaagent.thread;public class DieThread implements Runnable {public static Object obj1=new Object();public static Object obj2=new Object();private boolean flag;public DieThread(boolean bl){flag = bl;}@Overridepublic void run() {if(flag) {while(true) {synchronized(obj1) {try {Thread.sleep(1000);}catch (InterruptedException e){e.printStackTrace();}System.out.println("线程" + Thread.currentThread().getName() + "获取obj1锁对象,等待获取obj2锁对象...");synchronized(obj2) {System.out.println(Thread.currentThread().getName() + " ---- obj2.");}}}}else {while(true){synchronized(obj2) {System.out.println("线程" + Thread.currentThread().getName() + "获取obj2锁对象,等待获取obj1锁对象...");synchronized(obj1) {System.out.println(Thread.currentThread().getName() + " ---- obj1.");}}}}}
}

打开VisualVM检测到的JVM进程,我们可以看到这个tab在闪,VisualVM已经检测到死锁。

另外可以点击【线程 Dump】线程转储,进一步分析。

Java监控工具VisualVM相关推荐

  1. 【java】visualvm 插件 visual gc 使用介绍

    1.概述 转载:visualvm 插件 visual gc 使用介绍 visual gc 是 visualvm 中的图形化查看 gc 状况的插件. 具体详细介绍可参照: http://www.orac ...

  2. 使用Java监控工具出现 Can't attach to the process

    问题重现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 ➜ jinfo -flags 3032 Attaching ...

  3. java visualvm远程监控_深入理解JVM虚拟机12:JVM性能管理神器VisualVM介绍与实战

    本文转自互联网,侵删 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutori ...

  4. Java虚拟机性能管理神器 - VisualVM(2) 入门

    一下载VisualVM 最新版本下载 历史版本下载 二启动VisualVM 三VisualVM用户目录 四VisualVM窗口 1应用程序窗口 2详情窗口 五VisualVM插件 Java虚拟机性能管 ...

  5. 深入理解JVM—性能监控工具

    我们知道,在JVM编译期和加载器,甚至运行期已经做了大量的调优操作,但是那些都是JVM针对Java程序所做的通用的.简单的优化,程序在运行时由于运行环境的复杂性.业务逻辑的复杂性,很多JVM是无法进行 ...

  6. 一步步优化JVM四:决定Java堆的大小以及内存占用

    到目前为止,还没有做明确的优化工作.只是做了初始化选择工作,比如说:JVM部署模型.JVM运行环境.收集哪些垃圾回收器的信息以及需要遵守垃圾回收原则.这一步将介绍如何评估应用需要的内存大小以及Java ...

  7. java虚拟机学习笔记 【3】

    为什么80%的码农都做不了架构师?>>>    认识Java虚拟机的内部体系结构 Java虚拟机的内部体系结构也许很少有人去关心,因为对于Java程序员来说,一般只需要跟API打交道 ...

  8. JVM性能调优监控工具jps、jstack、jmap、jhat、jstat使用详解

    参考来自:周志明著 深入理解JAVA虚拟机 https://www.cnblogs.com/therunningfish/p/5524238.html http://www.tuicool.com/a ...

  9. JVM优化:决定Java堆的大小以及内存占用

    转载:https://blog.csdn.net/zhoutao198712/article/details/7783070    到目前为止,还没有做明确的优化工作.只是做了初始化选择工作,比如说: ...

最新文章

  1. Fiddler抓取手机(app)https包
  2. linux保存输出结果到txt
  3. 强烈推荐几个我常置顶阅读清华、哈工大的平台公众号!
  4. PyTorch 实现 Mask-RCNN
  5. Js-parentNode、parentElement,childNodes、children 它们有什么区别呢?
  6. return 返回值的问题
  7. java私有属性和私有方法_Java接口–历年来Java 9之旅–默认方法和私有方法
  8. java foward_java 中sendredirect()和forward()方法的区别
  9. Codewars-parseInt() reloaded(实现英文单词和数字的转换)
  10. 即时通讯开发----回音消除技术
  11. 有时间了要研究一下Stack Exchange的开源项目
  12. idea2020代码el组件红色波浪线_Android实现炫酷的ViewPager3D组件
  13. 计算机组成原理 第四章 指令系统
  14. 第8章 面向对象高级编程与网络编程
  15. mac上数据库管理工具Navicat Premium 连接mySQL
  16. 家用计算机的计算速度,计算机CPU运算速度是多少
  17. Java fx 变速播放音乐_QVE音频剪辑如何调整音频播放速度?音乐变速方法说明
  18. TZT3801G无线振弦在线监测系统
  19. 2069: [POI2004]ZAW
  20. java中国象棋兵吃棋规则_国际象棋兵吃子规则介绍_国际象棋吃子的理论介绍

热门文章

  1. 【转】SQL中where, group by, having的用法和区别
  2. 【转】1.5异步编程:.NET4.X 数据并行
  3. 【转】WCF、WebAPI、WCFREST、WebService之间的区别
  4. iis到w3wp的数据流及工作原理
  5. ABP入门系列(3)——领域层定义仓储并实现
  6. Qt应用程序发布:Qt应用程序添加版本版权生产商等信息
  7. MapReduce的shuffle阶段
  8. Python 数据结构之栈的实现
  9. git 连接gitee时报错 Auth error: Access deined: authorize failure
  10. oracle行转列 case,Oracle 行转列总结 Case When,Decode,PIVOT 三种方式