`
zorufa876
  • 浏览: 80905 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

好用的性能分析工具–VisualVM

阅读更多

最近在学TDA(Thread Dump Analyzer)的时候,发现一款很好用的查看JVM的工具–VisualVM,这个工具是Sun在JDK1.6 Update7之后的版本中推出的,就放在bin目录下面,惭愧的是我竟然一直都没发现。
    简单说来,VisualVM是jConsole的升级版,但它可比jConsole好用多了。它能为您提供强大的thread 和heap分析能力。它囊括的命令行工具包括 JConsole, jstack,jstat, jmap ,jps。具体怎么操作我就不说了,很简单,大家可以参考这几个网址:
VisualVM入门指南:https://visualvm.dev.java.net/zh_CN/gettingstarted.html
VIsualVM介绍:    http://www.iteye.com/topic/516447
jstatd介绍:      http://java.sun.com/javase/6/docs/technotes/tools/share/jstatd.html

下面我就提一下我在学习操作这个工具的过程中遇到的几个问题,不过在看问题一和问题二之前最好先阅读一下jstatd介绍会比较好。

问题一 :在服务端启动jstatd的时候,我执行的命令如下:jstatd -J-Djava.security.policy=jstatd.all.policy
我发现它会报
java.rmi.ConnectIOException: non-JRMP server at remote endpoint
        at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:230)
        at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:184)
        at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:322)
        at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
        at java.rmi.Naming.rebind(Naming.java:160)
        at sun.tools.jstatd.Jstatd.bind(Jstatd.java:40)
        at sun.tools.jstatd.Jstatd.main(Jstatd.java:126)
这个错误,而报这个错误的
原因是因为我在上面的命令中没有指定端口号,所以jstatd就采用默认的端口号1099,可是由于这个端口号已经被别的程序给占用了,所以会报上面这个 错误。因此,我就用指定的端口号来执行jstatd
比如:jstatd -J-Djava.security.policy=jstatd.all.policy -p 2222,问题就解决了。

问题二 :在执行了jstatd -J-Djava.security.policy=jstatd.all.policy -p 2222这个命令以后,后面又用ctrl+C把它给stop了,那么你再重新启动2222这一端口的jstatd的话,你会发现VisualVM调用不到 这个jstatd了,并且服务器过一会儿就会报:
java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is:
        java.net.SocketTimeoutException: Read timed out
        at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:286)
        at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:184)
        at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:322)
        at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
        at java.rmi.Naming.rebind(Naming.java:160)
        at sun.tools.jstatd.Jstatd.bind(Jstatd.java:40)
        at sun.tools.jstatd.Jstatd.main(Jstatd.java:126)
Caused by: java.net.SocketTimeoutException: Read timed out
        at java.net.SocketInputStream.socketRead0(Native Method)
        at java.net.SocketInputStream.read(SocketInputStream.java:129)
        at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
        at java.io.BufferedInputStream.read(BufferedInputStream.java:237)
        at java.io.DataInputStream.readByte(DataInputStream.java:248)
        at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:228)
        … 6 more
这样的错误。这是因为虽然jstatd被stop了,但是这个端口的进程还是存在的,所以要么你再换一个没用过的端口号,要么你把原来的还在被占用的端口 号给kill掉,然后重新启动jstack,再重新启动VisualVM,就可以了。
参考资料:

问题三 :点击VisualVM的“Profiler”tab的时候,会弹出一个没有任何提示信息的错误小框,如 下图:
 1
并且报这个错误
Exception in thread “Attach Listener” java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(Unknown Source)
        at sun.instrument.InstrumentationImpl.loadClassAndCallAgentmain(Unknown Source)
Caused by: java.lang.NullPointerException
        at org.netbeans.lib.profiler.server.ProfilerActivate15.getArchiveFile(ProfilerActivate15.java:75)
        at org.netbeans.lib.profiler.server.ProfilerActivate15.activate(ProfilerActivate15.java:96)
        at org.netbeans.lib.profiler.server.ProfilerActivate15.agentmain(ProfilerActivate15.java:61)
        … 6 more
查了很久,发现是我这个安装这个工具的目录路径中是有中文的,可能是因为中文的关系所以它在解析目录的时候出错了。虽然这个bug的原因比较白痴,不过通 过查资料,发现InvocationTargetException这个异常一般是在通过反射方式来获取接口的实际实现的方法时会抛出的。而这个异常由于 并没有覆盖getMessage方法,所以会弹出一个没有任何提示信息的小框了,也算是有收获。
参考资料:http://java.sun.com/j2se/1.4.2/docs/api/java/lang/reflect/InvocationTargetException.html
          http://blog.csdn.net/dingyuan963/archive/2009/07/09/4333071.aspx

 
会操作工具了,就来实际模拟一下怎么找bug吧,

一:查找线程死锁:
先写一段死锁的代码
public class TestDeadLock implements Runnable
{
 public int flag = 1;
 static Object o1= new Object();
 static Object o2 = new Object();
 public static void main(String[] args)
 {
  TestDeadLock td1 = new TestDeadLock();
  TestDeadLock td2 = new TestDeadLock();
  td1.flag=1;
  td2.flag=0;
  Thread t1 = new Thread(td1);
  Thread t2 = new Thread(td2);
  t1.start();
  t2.start();
 }

 public void run()
 {
  if(flag == 1){
   synchronized(o1){
    try
    {
     Thread.sleep(500);
    }
    catch (InterruptedException e)
    {
    }
    synchronized(o2){
     System.out.println(”1″);
    }
   }
  }
  if(flag==0){
   synchronized(o2){
    try
    {
     Thread.sleep(500);
    }
    catch (InterruptedException e){
    }
    synchronized(o1){
     System.out.println(”0″);
    }
   }
  }
 }

}

然后把这段代码放到linux服务端的应用中,随便把这段代码写到哪个类都行。接着再启动服务器,启动VisualVM的远程监控,然后执行这段代码。
你会很容易的发现在VisualVM的“线程”tab中有两条线程的颜色特别鲜艳,如下图:

 2
很明显,Thread-32和Thread-33是有问题的两条线程:
再按一下上图中的“线程 dump”按钮,找到这两个线程的详细信息:
 3
查看一下上图右下角有关于Thread33这个线程的详细信息,很明显,是MsmPlanList这个类有问题。

二:查找内存异常:
同样的,从激烟那里搞来他上次分享时写的能占用很多内存的代码
public class TestMemory {
 private List<Long> testMemory = new ArrayList<Long>();

 public void test(){
  if (testMemory.isEmpty()) {
   testMemory.add(0L);
  }

  if (testMemory.size() < Integer.MAX_VALUE – 1000000) {
   int start = testMemory.size() – 1;
   for (int i = 0; i < 1000000; i++) {
    testMemory.add((long) (start + i));
   }
  }
  
 }
}

随便把这段代码写到哪个类都行,然后运行 jboss服务器,执行指定的类,然后查看VisualVM中“监视”这个tab,看下图右下角四副图中的堆内存使用情况图,发 现每次执行程序,堆内存确实是大了一点。

 4

要想确定到底是调用哪个方法导致堆内存占用太多,需要点击“堆 dump”按钮(注1:),这一步需要一些时间,得到如下页面:

 5
通过“大小”的排序,发现java.util.Long所占用的内存是最大的。好,就查这个类的实例,双击它(注2:),得到如下页面:

6

然后由于这些实例是从小到大排序的,所以找到最后一个实例,如图:
 7

可以发现testMemory就是那个占用内存最大的实例了。

 
最后还想再提醒一句 ,VisualVM的功能是不止这些的,点击菜单栏上的工具->插件选项,你会发现 VisualVM还有很多好用的插件没安装,比如VisualVM-TDA-Module这个插件,它就是整合了TDA的功能的,至于其他的各位好好去发 掘吧。

注1: 对于“堆 dump”来说,在远程监控jvm的时候,VisualVM是没有这个功能的,只有本地监控的时候才有。另外,就算是本地监控,它在dump和得到实例的 速度那是相当的慢的。所以鉴于这几个原因,不建议用VisualVM,而是用jmap加上Mat来分析内存情况。

注2 :这里还想提醒的是,如果你在得到实例的过程中报了如下图的错误:
 8
那么,就表明你给VisualVM分配的堆内存不够,找到${visualvm}/etc/visualvm.conf 这个文件,修改
default_options=”-J-Xms24m -J-Xmx192m -J-为
default_options=”-J-Xms24m -J-Xmx1024m -J-
再重启VisualVM就行了。

分享到:
评论
3 楼 2110901055 2013-10-14  
对啊,图崩了,楼主可否把图补全。
2 楼 albert0312 2012-03-02  
好文章可惜图挂了~~
1 楼 278681694 2011-04-12  
你好、、图怎么挂了,能麻烦把图补上,最近正在寻找详细解释。谢谢

相关推荐

    可视化性能监控工具VisualVM

    可视化性能监控工具VisualVM

    Java程序性能分析工具 VisualVM_202.zip

    可以作为Java应用程序性能分析和运行监控的工具。开发人员可以利用它来监控、分析线程信息,浏览内存堆数据。系统管理员可以利用它来监测、控制Java应用程序横跨整个网络的情况。Java应用程序使用人员可以利用它来...

    Java多线程的监控分析工具(VisualVM).doc

    Java多线程的监控分析工具(VisualVM)

    VisualVM程序性能分析工具 v2.1.7.zip

    VisualVM程序性能分析工具 v2.1.7.zip

    VisualVM程序性能分析工具 v2.0.5

    为您提供VisualVM程序性能分析工具下载,VisualVM是一个集成多个JDK命令行工具的可视化工具。可以作为Java应用程序性能分析和运行监控的工具。开发人员可以利用它来监控、分析线程信息,浏览内存堆数据。系统管理员...

    JavaVisualVM可视化多线程监控分析工具v1.3.8官方安装版

    Java VisualVM是一个多线程的监控分析工具,VisualVM 是一款免费的\集成了多个 JDK 命令行工具的可视化工具,它能为您提供强大的分析能力,对 Java 应用程序做性能分析和调优。功能包括内存分析、快照功能、转储功能...

    visualVM性能优化工具

    最近在做Java大数据性能优化 觉得打印判断执行时间 线程使用太土 这个文档不错

    JVM性能监控工具VisualVM. Jconsole插件所需jar包 JTop.jar

    JVM性能监控工具VisualVM Jconsole插件所需jar包 JTop.jar 点击'JConsole Plugins'按钮 点击'Add JAR/Folder'按钮, 添加JDK_HOME/demo/management/JTop/JTop.jar7)重新打开监控页面,可以看到JConsole

    visualvm_14.zip

    性能分析神器VisualVM VisualVM 是一款免费的,集成了多个 JDK 命令行工具的可视化工具,它能为您提供强大的分析能力,对 Java 应用程序做性能分析和调优。

    JVM性能监控方法之visualVM1

    JVM性能监控方法之visualVM1

    VisualVM程序性能分析工具 v2.0.4

    为您提供VisualVM程序性能分析工具下载,VisualVM是一个集成多个JDK命令行工具的可视化工具。可以作为Java应用程序性能分析和运行监控的工具。开发人员可以利用它来监控、分析线程信息,浏览内存堆数据。系统管理员...

    Java内存监控工具Java VisualVM

    Java内存监控工具Java VisualVM

    VisualVM程序性能分析工具-其他

    可以作为Java应用程序性能分析和运行监控的工具。开发人员可以利用它来监控、分析线程信息,浏览内存堆数据。系统管理员可以利用它来监测、控制Java应用程序横跨整个网络的情况。Java应用程序使用人员可以利用它来...

    visualVm1.4.2分析工具.rar

    VisualVM 是一款免费的性能分析工具。它通过 jvmstat、JMX、SA(Serviceability Agent)以及 Attach API 等多种方式从程序运行时获得实时数据,从而进行动态的性能分析。

    Visualvm插件TDA(thread dump分析)

    https://java.net/projects/tda/downloads/directory/visualvm 官方下载的,附带使用方法,Visualvm的TDA插件,能很好的分析线程Dump日志,吐血推荐!

    jvm监控工具visualVM

    visualVM,放到%JAVA_HOME%\bin目录下即可。

    内存检测工具-visualvm-216

    VisualVM 是一款免费的,集成了多个 JDK 命令行工具的可视化工具,提供强大的分析能力,对 Java 应用程序做性能分析和调优。 在高版本JDK(大于1.8或后期更新的1.8版本)中已经不会再自动集成 VisualVM,需要下载独立...

    Visualvm工具

    Visualvm多合一故障处理工具

    visualvm, 在一个Java故障排除工具中,VisualVM是一个.zip

    visualvm, 在一个Java故障排除工具中,VisualVM是一个 ( 母版) 源库VisualVM是一个集成命令行JDK工具和轻量级分析能力的可视化工具。 有关详细信息,下载和文档,请参阅 https://visualvm.github.io 。获取工具使用...

    visualvm_137中文版

    visualvm_137中文版 java性能测试工具VisualVM

Global site tag (gtag.js) - Google Analytics