visualvm可以对应用软件性能需求分析进行性能分析吗

VisualVM 性能分析概述 - 蝈蝈俊 - 博客园
posts - 484, comments - 150, trackbacks - 0, articles - 0
VisualVM是一个免费的Java应用监控、分析工具。
简单说来,VisualVM是一种集成了多个JDK命令行工具的可视化工具,它能为您提供强大的分析能力。所有这些都是免费的!它囊括的命令行工具包括jstat, JConsole, jstack, jmap 和 jinfo,这些工具与JDK的标准版本是一致的。
你可以使用VisualVM生成和分析海量数据、跟踪内存泄漏、监控垃圾回收器、执行内存和CPU分析,同时它还支持在MBeans上进行浏览和操作。尽管VisualVM自身要在JDK6这个版本上运行,但是JDK1.4以上版本的程序它都能监控。
JDK1.6 Update7之后的版本中默认就带了 VisualVM,在bin目录下的 jvisualvm 就是:
Mac 下 JDK 默认安装在 /Library/Java/JavaVirtualMachines/版本号 目录下。
如果你想用最新版本的,则可以自行在
下载。最新版本是 1.3.8 (日发布的)
VisualVM 左侧导航中,我们可以看到它具有 “本地”、“远程”、“快照”等功能。如下图是我本地 XMind的监控情况。
下面的几个分析以 dubbo 的 demo 例子为例进行的截图。
在监视标签内,我们可以看到实时的应用程序内存堆以及永久保留区域的使用情况。
内存堆使用情况
永久保留区域使用情况
Heap跟PermGen的区别, 一般而言,PerGen放的是类的定义;而Heap里面放的是类的实例;所以一般程序稳定运行后,PermGen基本保持不变,要变也只会增加,因为GC只会扫描heap中的实例;而Heap变化较大,OutOfMemory一般也是Heap不够了。
OOM时对转存
此外,我们也可以通过 Applications 窗口右击应用程序节点来启用“在出现 OOME 时生成堆 Dump”功能,当应用程序出现 OutOfMemory 异常时,VisualVM 将自动生成一个堆转储。
内存分析结果
在 Profiler 标签,点击“内存”按钮将启动一个内存分析会话,等 VisualVM 收集和统计完相关性能数据信息,将会显示在性能分析结果。通过内存性能分析结果,我们可以查看哪些对象占用了较多的内存,存活的时间比较长等,以便做进一步的优化。
此外,我们可以通过性能分析结果下方的类名过滤器对分析结果进行过滤。
CPU使用情况
在监视标签内,我们可以查看 CPU 的使用率以及垃圾回收活动对性能的影响。过高的 CPU 使用率可能是由于我们的项目中存在低效的代码,可以通过 Profiler 标签的 CPU 性能分析功能进行详细的分析。如果垃圾回收活动过于频繁,占用了较高的 CPU 资源,可能是由内存不足或者是新生代和旧生代分配不合理导致的等。
CPU 性能分析结果
在 Profiler 标签,点击“CPU”按钮启动一个 CPU 性能分析会话 ,VisualVM 会检测应用程序所有的被调用的方法。当进入一个方法时,线程会发出一个“method entry”的事件,当退出方法时同样会发出一个“method exit”的事件,这些事件都包含了时间戳。然后 VisualVM 会把每个被调用方法的总的执行时间和调用的次数按照运行时长展示出来。
在 VisualVM 的监视标签内,我们可以查看当前应用程序中所有活动线程和守护线程的数量等实时信息。
线程标签的时间线视图上方的工具栏提供了缩小,放大和自适应三个按钮,以及一个下拉框,我们可以选择将所有线程、活动线程或者完成的线程显示在视图中。
我们可以使用 VisualVM 的快照功能生成任意个性能分析快照并保存到本地来辅助我们进行性能分析。快照为捕获应用程序性能分析数据提供了一个很便捷的方式因为快照一旦生成可以在任何时候离线打开和查看,也可以相互传阅。
Profiler 快照
Profiler 快照:当有一个性能分析会话(内存或者 CPU)正在进行时,我们可以通过性能分析结果工具栏的“快照”按钮生成 Profiler 快照捕获当时的性能分析数据。
产生的快照
应用程序快照
应用程序快照:我们可以右键点击左侧 Applications 窗口中应用程序节点,选择“应用程序快照”为生成一个应用程序快照。应用程序快照会收集某一时刻的堆转储,线程转储和 Profiler 快照,同时也会捕获 JVM 的一些基本信息。
线程转存的生成和分析
VisualVM 能够对正在运行的本地应用程序生成线程转储,把活动线程的堆栈踪迹打印出来,帮助我们有效了解线程运行的情况,诊断死锁、应用程序瘫痪等问题。
生成的信息:
堆转存的生成和分析
VisualVM 能够生成堆转储,统计某一特定时刻 JVM 中的对象信息,帮助我们分析对象的引用关系、是否有内存泄漏情况的发生等。
当 VisualVM 统计完堆内对象数据后,会把堆转储信息显示在新的堆转储标签内,我们可以看到摘要、类、实例数等信息以及通过 OQL 控制台执行查询语句功能。
堆转储的摘要包括转储的文件大小、路径等基本信息,运行的系统环境信息,也可以显示所有的线程信息。
堆转储的类视图
从类视图可以获得各个类的实例数和占用堆大小数,分析出内存空间的使用情况,找出内存的瓶颈,避免内存的过度使用。
通过实例数视图可以获得每个实例内部各成员变量的值以及该实例被引用的位置。首先需要在类视图选择需要查看实例的类。
此外,还能对两个堆转储文件进行比较。通过比较我们能够分析出两个时间点哪些对象被大量创建或销毁。
线程转储和堆转储均可以另存成文件,以便进行离线分析。
参考资料:
使用 VisualVM 进行性能分析及调优VisualVM中文版下载|Java VisualVM下载 v1.3.8 官方版_最火软件站
您的位置: >
> Java VisualVM v1.3.8 官方版下载
Java VisualVM v1.3.8 官方版
论坛转帖:
分&享&到:
Java VisualVM 1.3.8 中文版来自官方网站,此版本为官方最新,VisualVM 是一个集成多个命令行工具的可视化监控分析工具。它能为您提供强大的分析能力,对 Java 应用程序做性能分析和调优。可以作为Java应用程序性能分析和运行监控的工具。
开发人员可以利用它来监控、分析线程信息、跟踪内存泄漏、监控垃圾回收器、执行内存和 CPU 分析,同时它还支持在 MBeans 上进行浏览和操作。系统管理员可以利用它来监测、控制Java应用程序横跨整个网络的情况。Java应用程序使用人员可以利用它来创建包含所有必要信息的Bug 报告。
VisualVM 概述
开发大型 Java 应用程序的过程中难免遇到内存泄露、性能瓶颈等问题,比如文件、网络、数据库的连接未释放,未优化的算法等。随着应用程序的持续运行,可能会造成整个系统运行效率下降,严重的则会造成系统崩溃。为了找出程序中隐藏的这些问题,在项目开发后期往往会使用性能分析工具来对应用程序的性能进行分析和优化。
VisualVM是JDK的一个集成的分析工具,自从JDK 6 Update 7以后已经作为Sun的JDK的一部分。VisualVM 是一款免费的性能分析工具。它通过 jvmstat、JMX、SA(Serviceability Agent)以及 Attach API 等多种方式从程序运行时获得实时数据,从而进行动态的性能分析。同时,它能自动选择更快更轻量级的技术尽量减少性能分析对应用程序造成的影响,提高性能分析的精度。
点击链接开始下载性能分析神器VisualVM - WadeXu - 博客园
-- 拓展测试的边界
posts - 23, comments - 105, trackbacks - 0, articles - 0
VisualVM 是一款免费的,集成了多个 JDK 命令行工具的可视化工具,它能为您提供强大的分析能力,对 Java 应用程序做性能分析和调优。这些功能包括生成和分析海量数据、跟踪内存泄漏、监控垃圾回收器、执行内存和 CPU 分析,同时它还支持在 MBeans 上进行浏览和操作。本文主要介绍如何使用 VisualVM 进行性能分析及调优。
内存分析篇
内存堆Heap
永久保留区域PermGen
线程分析篇
自从 JDK 6 Update 7 以后已经作为 Oracle JDK 的一部分,位于 JDK 根目录的 bin 文件夹下,无需安装,直接运行即可。
内存分析篇
VisualVM 通过检测 JVM 中加载的类和对象信息等帮助我们分析内存使用情况,我们可以通过 VisualVM 的监视标签对应用程序进行内存分析。
1)内存堆Heap
首先我们来看内存堆Heap使用情况,我本机eclipse的进程在visualVM显示如下:
随便写个小程序占用内存大的,运行一下
程序如下:
package jvisualVM;
public class JavaHeapTest {
public final static int OUTOFMEMORY = ;
private int
StringBuffer tempOOM = new StringBuffer();
public JavaHeapTest(int leng) {
this.length =
int i = 0;
while (i & leng) {
tempOOM.append("a");
} catch (OutOfMemoryError e) {
e.printStackTrace();
this.oom = tempOOM.toString();
public String getOom() {
public int getLength() {
public static void main(String[] args) {
JavaHeapTest javaHeapTest = new JavaHeapTest(OUTOFMEMORY);
System.out.println(javaHeapTest.getOom().length());
查看VisualVM Monitor tab, 堆内存变大了
在程序运行结束之前, 点击Heap Dump 按钮, 等待一会儿,得到dump结果,可以看到一些Summary信息
点击Classes,&发现char[]所占用的内存是最大的
双击它,得到如下Instances结果
&Instances是按Size由大到小排列的
第一个就是最大的, 展开Field区域的 values
StringBuffer类型的 全局变量 tempOOM 占用内存特别大, 注意局部变量是无法通过 堆dump来得到分析结果的。
另外,对于&堆 dump&来说,在远程监控jvm的时候,VisualVM是没有这个功能的,只有本地监控的时候才有。
&###转载注明出处:&
2)永久保留区域PermGen
其次来看下永久保留区域PermGen使用情况
运行一段类加载的程序,代码如下:
package jvisualVM;
import java.io.F
import java.lang.reflect.M
import java.net.MalformedURLE
import java.net.URL;
import java.net.URLClassL
import java.util.ArrayL
import java.util.L
public class TestPermGen {
private static List&Object& insList = new ArrayList&Object&();
public static void main(String[] args) throws Exception {
permLeak();
private static void permLeak() throws Exception {
for (int i = 0; i & 1000; i++) {
URL[] urls = getURLS();
URLClassLoader urlClassloader = new URLClassLoader(urls, null);
Class&?& logfClass = Class.forName("mons.logging.LogFactory", true,urlClassloader);
Method getLog = logfClass.getMethod("getLog", String.class);
Object result = getLog.invoke(logfClass, "TestPermGen");
insList.add(result);
System.out.println(i + ": " + result);
private static URL[] getURLS() throws MalformedURLException {
File libDir = new File("C:/Users/wadexu/.m2/repository/commons-logging/commons-logging/1.1.1");
File[] subFiles = libDir.listFiles();
int count = subFiles.
URL[] urls = new URL[count];
for (int i = 0; i & i++) {
urls[i] = subFiles[i].toURI().toURL();
一个类型装载之后会创建一个对应的java.lang.Class实例,这个实例本身和普通对象实例一样存储于堆中,我觉得之所以说是这是一种特殊的实例,某种程度上是因为其充当了访问PermGen区域中类型信息的代理者。
运行一段时间后抛OutOfMemoryError了, VisualVM监控结果如下:
结论:PermGen区域分配的堆空间过小,我们可以通过设置-XX: PermSize参数和-XX:MaxPermSize参数来解决。
关于PermGen OOM深入分析请参考
关于Perform GC, 请参考
这部分知识还是比较深入的,有空还要继续研究。
###转载注明出处:&
CPU 性能分析的主要目的是统计函数的调用情况及执行时间,或者更简单的情况就是统计应用程序的 CPU 使用情况。
没有程序运行时的 CPU 使用情况如下图:
运行一段 占用CPU 的小程序,代码如下
package jvisualVM;
public class MemoryCpuTest {
public static void main(String[] args) throws InterruptedException {
* cpu 运行固定百分比
* @throws InterruptedException
public static void cpuFix() throws InterruptedException {
// 80%的占有率
int busyTime = 8;
// 20%的占有率
int idelTime = 2;
// 开始时间
long startTime = 0;
while (true) {
// 开始时间
startTime = System.currentTimeMillis();
* 运行时间
while (System.currentTimeMillis() - startTime & busyTime) {
// 休息时间
Thread.sleep(idelTime);
查看监视页面 Monitor tab
过高的 CPU 使用率可能是由于我们的项目中存在低效的代码;
在我们对程序施压的时候,过低的 CPU 使用率也有可能是程序的问题。
点击取样器Sampler, 点击&CPU&按钮, 启动CPU性能分析会话,VisualVM 会检测应用程序所有的被调用的方法,
在CPU samples tab 下可以看到我们的方法cpufix() 的自用时间最长, 如下图:
切换到Thread CPU Time 页面下,我们的 main 函数这个进程 占用CPU时间最长, 如下图:
&###转载注明出处:&
线程分析篇
Java 语言能够很好的实现多线程应用程序。当我们对一个多线程应用程序进行调试或者开发后期做性能调优的时候,往往需要了解当前程序中所有线程的运行状态,是否有死锁、热锁等情况的发生,从而分析系统可能存在的问题。
在 VisualVM 的监视标签内,我们可以查看当前应用程序中所有活动线程(Live threads)和守护线程(Daemon threads)的数量等实时信息。
运行一段小程序,代码如下:
package jvisualVM;
public class MyThread extends Thread{
public static void main(String[] args) {
MyThread mt1 = new MyThread("Thread a");
MyThread mt2 = new MyThread("Thread b");
mt1.setName("My-Thread-1 ");
mt2.setName("My-Thread-2 ");
mt1.start();
mt2.start();
public MyThread(String name) {
public void run() {
while (true) {
Live threads 从11增加两个 变成13了
Daemon threads从8增加两个 变成10了&
VisualVM 的线程标签提供了三种视图,默认会以时间线的方式展现, 如下图:
可以看到两个我们run的程序里启的线程:My-Thread-1 和&My-Thread-2
另外还有两种视图分别是表视图和详细信息视图, 这里看一下每个Thread的详细视图:
&###转载注明出处:&
再来一段死锁的程序,看VisualVM 能否分析出来
package jvisualVM;
public class DeadLock {
public static void main(String[] args) {
Resource r1 = new Resource();
Resource r0 = new Resource();
Thread myTh1 = new LockThread1(r1, r0);
Thread myTh0 = new LockThread0(r1, r0);
myTh1.setName("DeadLock-1 ");
myTh0.setName("DeadLock-0 ");
myTh1.start();
myTh0.start();
class Resource {
private int
public int getI() {
public void setI(int i) {
class LockThread1 extends Thread {
private Resource r1, r2;
public LockThread1(Resource r1, Resource r2) {
this.r1 = r1;
this.r2 = r2;
public void run() {
int j = 0;
while (true) {
synchronized (r1) {
System.out.println("The first thread got r1's lock " + j);
synchronized (r2) {
System.out.println("The first thread got r2's lock
class LockThread0 extends Thread {
private Resource r1, r2;
public LockThread0(Resource r1, Resource r2) {
this.r1 = r1;
this.r2 = r2;
public void run() {
int j = 0;
while (true) {
synchronized (r2) {
System.out.println("The second thread got r2's lock
synchronized (r1) {
System.out.println("The second thread got r1's lock" + j);
打开VisualVM检测到的JVM进程,我们可以看到这个tab在闪,VisualVM已经检测到我这个package下面的DeadLock类出错了
切换到Thread tab, 可以看到死锁了, Deadlock detected!
另外可以点击Thread Dump 线程转储,进一步分析,在这里就不赘述了,有兴趣的读者可以自行实验。
参考文献:
/developerworks/cn/java/j-lo-visualvm/
通过本文的介绍,相信读者已经对性能分析有一个初步的了解了,如果您觉得本文的内容对您的学习有所帮助,您可以点击右下方的推荐按钮,您的鼓励是我创作的动力。
转载注明出处:&jvm参数实战:VisualVM工具对Eclipse性能调优 -
- ITeye技术网站
博客分类:
VisualVM 是一个功能强大的运行监视和故障处理工具,自从 以后已经作为 的一部分,位于 根目录的 文件夹下。其性能分析功能甚至比起、等专业且收费的工具都不会逊色多少。而且还有一个很大的优点:不需要被监视的程序基于特殊运行,因此它对应用程序的实际性能影响很小,使得它可以直接应用于生产环境中。这个优点是、等工具无法与之媲美的。
使用之前可以根据需要下载安装合适的插件
1、插件中心安装:
主菜单中选择“工具”“插件”。在“可用插件”标签中,选中该插件的“安装”复选框。单击“安装”。
2、手动安装:主菜单中选择“工具”“插件”,在“已下载”标签中,点击添加插件按钮,选择已下载的插件文件 并打开。
插件下载地址
VisualVM详细使用可参考
二、Eclipse调优
1、未调整以前分析
Eclipse.ini中关于参数的原始配置如下:
--launcher.XXMaxPermSize
将(见附件)放到目录下,可以显示Eclipse启动耗时,如下图所示:
图二耗时统计插件显示
图二.2 VisualVM 的情况
未优化以前Eclipse启动分析如下:
■整个启动过程平均耗时约13秒。
■垃圾收集总耗时3.177秒 ,其中
Full GC被触发了12次,耗时2.942秒;
Minor GC触发36次,耗时0.235秒。
■加载类9663个,共耗时11.229秒
■虚拟机256MB( -Xmx256m)堆内存分配170.688MB给老年代(Old Gen),85.312MB给新生代(68.312MB给Eden,两个Surviver分别为8.5MB)。
2、参数调整分析
新生代Minor GC频繁,是由于虚拟机分配给新生代的空间太小而导致的,有必要使用-Xmn参数调整。
12次的Full GC大约耗时3秒,占了大部分的GC时间,降低GC时间的主要目标就是降低这部分时间。通过查看GC日志分析(-XX:+PrintGCDetails 打印GC详细信息 -Xloggc:mygc.log 位于eclipse.exe同目录下)
7.487: [Full GC 7.487: [Tenured: 18826K-&20090K(27328K), 0.1591992 secs] 22161K-&2K), [Perm : 20479K-&2K)], 0.1593305 secs] [Times: user=0.16 sys=0.00, real=0.16 secs]
8.532: [Full GC 8.532: [Tenured: 20781K-&23470K(33484K), 0.1794857 secs] 31767K-&2K), [Perm : 24575K-&2K)], 0.1796180 secs] [Times: user=0.19 sys=0.00, real=0.19 secs]
9.280: [Full GC 9.280: [Tenured: 23470K-&25873K(39120K), 0.2306239 secs] 30999K-&2K), [Perm : 28671K-&2K)], 0.2307639 secs] [Times: user=0.25 sys=0.00, real=0.25 secs]
10.717: [Full GC 10.717: [Tenured: 26054K-&28920K(43124K), 0.2285320 secs] 33607K-&2K), [Perm : 32767K-&3K)], 0.2286774 secs] [Times: user=0.22 sys=0.02, real=0.23 secs]
括号中的红色数字代表老年代容量,这组日志显示是老年代的空间耗尽,每发生一次都伴随着一次老年代空间扩容:。
通过分析可知:启动时的大多数是由于老年代扩容导致的,由永久代(Perm )扩容导致的也有一部分。为了避免这些扩容所带来的性能浪费,可以把和参数分别设置为和参数值,强迫虚拟机在启动的时候就把老年代和永久代容量固定下来,避免运行时自动扩展。
eclipse.ini 中参数为
-XX:PermSize=96m
-XX:MaxPermSize=96m
使用这个配置之后次数已经大幅降低,启动时间变为秒左右。
在有些情况下,曲线一直平滑,但还是发生。
此时用 进程号 命令查询一下最近一次的原因。有可能是代码调用了,显式触发了。在内存设置调整后,这种不符合我们的期望。因此在中加入参数屏蔽掉。
C:\Documents and Settings\Administrator&jps
C:\Documents and Settings\Administrator&jstat -gccause 10008
System.gc()
下载次数: 2
浏览: 3396 次
来自: 青岛
你好,你这么做可以导出vs文件吗

我要回帖

更多关于 应用性能分析 的文章

 

随机推荐