Java监控工具VisualVM

目录

  • 一、简介
  • 二、内存分析
    • 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】线程转储,进一步分析。
线程
线程死锁堆栈

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/446853.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

对官方Mutexes的翻译

参考链接 参考链接 Mutexes Whats A Mutex?Mutex OperationsBoost.Interprocess Mutex Types And HeadersScoped lockAnonymous mutex exampleNamed mutex example Whats A Mutex? 互斥是相互排斥的意思&#xff0c;它是进程之间最基本的同步形式。互斥保证只有一个线程可…

计算机应用基础

计算概论知识点 1.计算机之父&#xff1a;冯.诺伊曼 计算机基本组成&#xff1a;运算器&#xff0c;控制器&#xff0c;存储器&#xff0c;输入设备&#xff0c;输出设备 2.几种计算机&#xff1a;台式计算机,笔记本式计算机,PC服务器,平板式计算机… 3.电脑的硬件&#xff1a;…

Android最全UI库合集

目录抽屉菜单ListViewWebViewSwitchButton按钮点赞按钮进度条TabLayout图标下拉刷新ViewPager图表(Chart)菜单(Menu)浮动菜单对话框空白页滑动删除手势操作RecyclerViewCardColorDrawableSpinner布局模糊效果TabBarAppBar选择器(Picker)跑马灯日历时间主题样式ImageView通知聊天…

对于boost锁机制结论性的介绍

Conditions Whats A Condition Variable?Boost.Interprocess Condition Types And HeadersAnonymous condition example Whats A Condition Variable? 在前面的例子中&#xff0c;一个mutex被用来锁定&#xff0c;但我们不能用它来有效地等待&#xff0c;直到满足继续的条件…

C++数据类型

C 数据类型 |–基本数据类型: 整型 short短整型 2 int基本整型4 long长整型 8 浮点型 float单精度型 4 double双精度型 8 long double长双精度型 16 字符型 char 1 逻辑型 bool 1 空类型 void |–构造类型 数组类型 构造体类型 struct 共用体类型 union 枚举类型 enum 类类型…

Android Gradle 多渠道打包、动态配置AppName

目录一、简介二、Gradle多渠道打包1、普通做法2、Gradle多渠道打包一、简介 因为国内Android应用分发市场的现状&#xff0c;我们在发布APP时&#xff0c;一般需要生成多个渠道包&#xff0c;上传到不同的应用市场。这些渠道包需要包含不同的渠道信息&#xff0c;在APP和后台交…

boost锁机制中Semaphores的介绍

结构 Whats A Semaphore?Boost.Interprocess Semaphore Types And HeadersAnonymous semaphore example Whats A Semaphore? 旗语是一种基于内部计数的进程间同步机制&#xff0c;它提供了两种基本操作。等待&#xff1a;测试旗语数的值&#xff0c;如果小于或等于0&#x…

Android Gradle 批量修改生成的apk文件名

目录一、简介二、代码实现1、 Gradle 3.0以下版本2、Gradle 3.0以上版本一、简介 平时开发都知道&#xff0c;我们要上线的时候需要在Android studio打包apk文件&#xff0c;可是默认的打包名是app-release.apk或者app-debug.apk这样的名字&#xff0c;太没有辨识度了。 下面…

C++boost Class named_condition翻译

Class named_condition boost::interprocess::named_condition 简介 // In header: <boost/interprocess/sync/named_condition.hpp>class named_condition { public:// construct/copy/destructnamed_condition(create_only_t, const char *, const permissions &…

Android Studio 代理设置以及代理完全清除

目录一、代理设置二、代理完全清除一、代理设置 首先我们来看下怎样设置代理&#xff0c;Mac下打开【Preferences…】&#xff0c;然后搜索"HTTP"&#xff0c;选择【HTTP Proxy】&#xff0c;按图中设置配置好后&#xff0c;点击【Apply】&#xff0c;然后在点击【O…

安卓布局位置,dp与px的区别

手机6寸—指对角线 布局位置 横轴—x轴 纵轴—y轴 一个像素点 dp与Px dp:设备无关像素,与像素密度相关,像素距离 dpi:像素密度,每英寸包含的像素数 px:屏幕上一个物理像素点 ldpi低密度 1dp0.75px mdpi中密度 1dp1px hdpi高密度 1dp1.5px xhdpi超高密度 1dp2px xxhdpi超…

Android Studio 快捷键大全(Mac系统)

目录一、Mac上的按键符号二、快捷键查找/查看相关控制操作相关代码重构相关一、Mac上的按键符号 符号说明⌥option / alt⇧shift⌃control⌘command⎋esc 二、快捷键 查找/查看相关 快捷键说明双击 shift搜索任意内容command F / command R当前文件查找/替换&#xff0c;使…

ubuntu下clion软件连接boost库文件

整体配置 cmake_minimum_required(VERSION 3.17) project(mutex_learn)set(CMAKE_CXX_STANDARD 14) #boost库所在的根目录set(BOOST_ROOT "/usr/local/include/boost") #添加头文件搜索路径 include_directories(/usr/local/include) #添加库文件搜索路径 link_dir…

Android程序结构

Project方式 .gradle文件夹:编译相关生成 .idea文件夹:idea生成 app文件夹----应用程序的源代码和资源 build----编译后的文件存放的位置,最终apk文件存放的位置 libs:存放.jar和.so文件 src:AndroidTest与test存放测试相关的内容 main中Java文件夹存放Java源码,res文件…

通过Github创建Android库供其他项目依赖引用

目录一、简介二、实现第一步&#xff1a;将自己的项目托管到Github上。第二步&#xff1a;点击releases。第三步&#xff1a;创建release。第四步&#xff1a;填写版本号、名称、描述信息。第五步&#xff1a;点击【Publish release】。第六步&#xff1a;复制项目路径。第七步…

使用boost模板函数实现读写锁

介绍 shared_mutex即读写锁&#xff0c;不同与我们常用的独占式锁mutex&#xff0c;shared_mutex是共享与独占共存的锁&#xff0c;实现了读写锁的机制&#xff0c;即多个读线程一个写线程&#xff0c;通常用于对于一个共享区域的读操作比较频繁&#xff0c;而写操作比较少的情…

安卓内边距padding与外边距magrin

内边距padding与外边距margin 内边距只有容器才有,即里面要有视图 具体示例

Android Studio发布项目到jcenter

目录一、创建Bintray账户及Maven仓库二、上传项目到jcenter1、配置Android项目2、Gradle命令上传3、在项目中引用4、Add to JCenter三、Demo示例一、创建Bintray账户及Maven仓库 1、打开Bintray首页&#xff0c;点击 For an Open Source Account &#xff0c;快速注册或者用第…

C++读取文件,将文件内容读到string字符串里面

使用stringstream和ifstream实现 代码 std::ifstream f{file_name, std::ios::binary};std::stringstream ss;ss << f.rdbuf();auto data ss.str();