zoukankan      html  css  js  c++  java
  • Java性能监控工具:VisualVM

    VisualVM是JDK自带的一款全能型性能监控和故障分析工具,包括对CPU使用、JVM堆内存消耗、线程、类加载的实时监控,内存dump文件分析,垃圾回收运行情况的可视化分析等,对故障排查和性能调优很有帮助。在windows中安装JDK后,VisualVM位于%JAVA_HOME%/bin/下,直接执行jvisualvm.exe即可。

    VisualVM连接远程服务器有两种方式:JMX和jstatd,两种方式都不能完美支持所有功能,例如JMX不支持VisualGC,jstatd不支持CPU监控,实际使用可同时配置上并按需选用。

    双击启动 Java VisualVM 后可以看到窗口左侧 "应用程序 "栏中有" 本地 "、"远程 " 、"快照 "三个项目。

     "本地 "下显示的是在 localhost 运行的 Java 程序的资源占用情况,如果本地有 Java 程序在运行的话启动 Java VisualVM 即可看到相应的程序名,点击程序名打开相应的资源监控菜单,以图形的形式列出程序所占用的 CPU 、 Heap 、 PermGen 、类、线程的 统计信息。

    "远程" 项下列出的远程主机上的 Java 程序的资源占用情况,但需要在远程主机上运行 jstatd 守护程序

    VisualVM分为 3 类, 本地 它会自动侦测到,并显示出来.

    现在启动IDEA.

    双击Local 下的任一节点,看到右边的变化 ,你可以监控 CPU ,内存,类,线程等运行状况,实时监控服务器性能。

     

     右键 VisualVM我们可以看到 Thread Dump, Heap Dump

     做 Thread Dump 很快,马上就可以看到结果

     

     

     Heap Dump要稍花费一些时间(可以看到当前 heap 里对象的数量及占用的比例,做 OOM 很好用)

     

    二.使用visualvm 远程监控 JVM  

     1. 在服务器上安装 jstatd 组件

    jstatd工具是一个RMI服务器应用程序,主要用于监控HotSpot Java 虚拟机的创建与终止,并提供一个接口以允许远程监控工具附加到本地主机上运行的JVM上。

    使用apt-get 命令安装 openjdk 即可 :

    sudo apt-get install openjdk-6-jdk  

    2.在服务器上配置 jstatd 的 security policy 文件

    jstatd是一个监控 JVM 从创建到销毁过程中资源占用情况并提供远程监控接口的 RMI ( Remote Method Invocation ,远程方法调用)服务器程序,它是一个 Daemon 程序,要保证远程监控软件连接到本地的话需要 jstatd 始终保持运行。 

    jstatd运行需要通过 -J-Djava.security.policy=*** 指定安全策略,因此我们需要在服务器上建立一个指定安全策略的文件jstatd.all.policy ,文件内容如下:

    grant codebase "file:${java.home}/../lib/tools.jar" {
       permission java.security.AllPermission;
    };

    3. 修改服务器 hosts 文件中的 IP 地址

    要使Java VisualVM 成功连接到远程服务器上,服务器端应该在 /etc/hosts 文件中把本机地址设为本机的 IP 地址。使用 hostname -i 命令查看,如果显示的是 127.0.0.1 或者与本机实际 IP 不一致的话,需要把 /etc/hosts 文件中相应的地址改为本机实际 IP 。

    4.运行 jstatd 守护程序

     jstatd 需要保持一直运行,执行 jstatd 程序,命令如下:

    jstatd -J-Djava.security.policy=jstatd.all.policy

    5.通过Java VisualVM 连接到服务器监控 Java 程序

    在Java VisualVM 程序窗口左侧 " 远程 " 项目右键选择 " 添加远程主机 " ,在弹出的对话框中输入远程主机的 IP 地址,确认提交后即可看到相应的远程主机和在上面运行的 Java 程序,连接成功后应该会显示 Jstatd 及其 PID 。

    右击远程 选择添加远程主机:

    如果重新指定了jstatd端口,选择高级设置修改端口,如下图:默认端口为1099  

     

    添加后如图所示: 

     

    三:Tomcat配置JMX 

    用hostname -i 查看是否为127.0.0.1,这步非常重要,否则会连接失败,如果是,必须要配置-Djava.rmi.server.hostname 比如我的配置为 -Djava.rmi.server.hostname=192.168.8.7,而不需要修改hosts文件,修改此文件还可能影响到其他程序。 
    只需要在TOMCAT_HOME/bin/找到catalina.sh 加上以下参数,重新启动tomcat就可以了: 

    JAVA_OPTS="$JAVA_OPTS -Djava.rmi.server.hostname=192.168.8.7  
    -Dcom.sun.management.jmxremote.port=8088  
    -Dcom.sun.management.jmxremote.ssl=false  
    -Dcom.sun.management.jmxremote.authenticate=false"  

    注:1. -Dcom.sun.management.jmxremote.port :这个是配置远程 connection 的端口号的,要确定这个端口没有被占用

    2. -Dcom.sun.management.jmxremote.ssl=false 指定了 JMX 是否启用 ssl

    3. -Dcom.sun.management.jmxremote.authenticate=false   指定了JMX 是否启用鉴权(需要用户名,密码鉴权)

       2,3两个是固定配置,是 JMX 的远程服务权限的

    4. -Djava.rmi.server.hostname :这个是配置 server 的 IP 的

    打开JAVA_HOME/bin/下的jvisualvm 或者jconsole 的工具可以直接连接了,如下图visualvm连接的示意图: 

     也可以写个Java类TestJMXClient.java测试下JMX连接是否成功:

    import java.util.HashMap;  
    import java.util.Map;  
      
    import javax.management.MBeanServerConnection;  
    import javax.management.remote.JMXConnector;  
    import javax.management.remote.JMXConnectorFactory;  
    import javax.management.remote.JMXServiceURL;  
      
    /** 
     * @author Michael 
     */  
    public class TestJMXClient {  
      
        /** 
         * @param args 
         */  
        public static void main(String[] args) {  
            try {  
                String jndiPath = "jmxrmi";  
                String serverhost = "192.168.8.7";  
                String serverport = "8088";  
                // url=service:jmx:rmi:///jndi/rmi://192.168.8.7:8088/jmxrmi  
                String jmxurl = "service:jmx:rmi:///jndi/rmi://" + serverhost + ":"  
                        + serverport + "/" + jndiPath;  
                System.out.println("jmxurl:" + jmxurl);  
                JMXServiceURL url = new JMXServiceURL(jmxurl);  
                Map<String, Object> enviMap = new HashMap<String, Object>();  
      
                JMXConnector connector = JMXConnectorFactory.connect(url, enviMap);  
      
                MBeanServerConnection mbsc = connector.getMBeanServerConnection();  
                System.out.println("successful connected ");  
                connector.close();  
                System.out.println("close connect");  
            } catch (Exception e) {  
                System.out.println("error");  
                e.printStackTrace();  
            }  
        }  
    }  

     参考:

    http://ihuangweiwei.iteye.com/blog/1219302

    http://sjsky.iteye.com/blog/705323

    http://www.cnblogs.com/wade-xu/p/4369094.html

    http://www.cnblogs.com/leocook/p/jvisualvmandtomcat.html

    http://blog.csdn.net/autfish/article/details/51326340

  • 相关阅读:
    关系型数据库和非关系型数据库的区别
    总结篇3-python数据结构和算法
    总结篇2-python进阶
    总结篇1-python基础
    测试sql星级判定函数
    1、Anyproxy简介
    Python内置logging模块-- 日志
    python+ selenium 绕过浏览器检测
    python-selenium,解决 遇到阿里无痕登录验证
    seldom
  • 原文地址:https://www.cnblogs.com/winner-0715/p/7173792.html
Copyright © 2011-2022 走看看