zoukankan      html  css  js  c++  java
  • 性能监控之可视化故障处理工具 Visualvm

    1.Visualvm兼容范围与插件安装

      Visualvm基于NetBeans平台开发工具,具备通过插件扩展功能的能力。有了插件扩展功能,Visualvm可以做到:

    • 显示虚拟机进程以及进程的的配置,环境信息(jps,jinfo)
    • 监视应用存储的处理器,垃圾收集,堆,方法区以及线程的信息(jstat,jstack)
    • dump及分析堆转储快照(jmap,jhat)
    • 方法级的程序运行性能分析,找出被调用最多,运行时间最长的方法
    • 离线程序快照:收集程序的运行时配置,线程dump,内存dump等信息建立一个快照,可以将快照发送给开发者进行Bug反馈

    2.生成,浏览堆转储快照

      生成堆转储快照有两种方式:

    • 在“应用程序”窗口中右键应用程序节点,选择“堆Dump"
    • 在“应用程序”窗口中双击应用程序节点,打开应用程序标签,然后在”监视“标签中单击”堆Dump“

      [heapdump]文件是临时文件,需要手动保存。手动保存的dump文件可以通过 文件 -> 装入 功能打开

      

     

    3.程序性能分析

      在Profiler页签中,Visualvm提供了程序运行期间方法级的处理器执行时间分析和内存分析。做Profiling分析对程序运行性能有较大影响,所以一般不会在生产环境使用该功能。

    4.BTrace动态日志追踪

      Btrace的作用是在不中断目标程序运行的前提下,通过HotSpot的Instrument功能动态添加原本不存在的调试代码。

    package com.ryj.hotspot;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import com.ryj.java8.lambda.apple.Apple;
    
    public class JavaHeapTest {
    
        static List<Apple> appleList = new ArrayList<>();
    
        public static void main(String[] args) {
            verificationOOM();
        }
    
        private static void verificationOOM() {
            Integer i = 0;
            while (true) {
                addApple(++i);
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
    
        }
    
        private static Apple addApple(Integer a) {
            System.out.println(a);
            Apple apple = new Apple("red", 12.5f); 
            appleList.add(apple);
            return  apple;
        }
    }
    View Code
    /* BTrace Script Template */
    import com.sun.btrace.annotations.*;
    import com.alibaba.fastjson.JSON;
    import static com.sun.btrace.BTraceUtils.*;
    
    @BTrace(unsafe = true)
    public class TracingScript {
    	/* put your code here */
        @TLS private static long startTime = 0;
    
        @OnMethod(clazz="com.ryj.hotspot.JavaHeapTest",method="addApple")
        public static void startExecute(){
           startTime = timeNanos();
           //println(strcat("开始时间: ",str(startTime)));
        }
       
       @OnMethod(clazz="com.ryj.hotspot.JavaHeapTest",method="addApple",location=@Location(Kind.RETURN))
        public static void endExecute(@Self com.ryj.hotspot.JavaHeapTest instance, Integer a, @Return com.ryj.java8.lambda.apple.Apple apple){
           long endTime = timeNanos();
           //println(strcat("结束时间: ",str(endTime)));
           println(strcat("方法参数A: ",str(a)));
           println(strcat("execute time(nanos): ", str(endTime-endTime)));
           //println(strcat("result: ", str(apple.toString())));  
           println(strcat("result: ", JSON.toJSONString(apple)));
       }
    }
    View Code

      Btrace之所以安全可靠的,是因为它对正在运行的程序是只读的。也就是说,他可以插入跟踪语句来检测和分析运行中的程序,不允许对其进行修改。因此他存在一些限制:

    • 不能创建对象
    • 不能创建数组
    • 不能抛出和捕获异常
    • 不能调用任何对象方法和静态方法
    • 不能给目标程序中的类静态属性和对象的属性进行赋值
    • 不能有外部、内部和嵌套类
    • 不能有同步块和同步方法
    • 不能有循环(for, while, do..while)
    • 不能继承任何的类
    • 不能实现接口
    • 不能包含assert断言语句

      这些限制其实是可以使用unsafe模式绕过,通过声明 *@BTrace(unsafe = true) annotation。实际使用非安全模式跟踪时,发现一个问题,一个进程如果被安全模式btrace探测过一次, 后面再使用非安全模式进行探测时非安全模式不生效。

    • @BTrace 声明了这个类是BTrace脚本。unsafe参数表示是否不安全的模式执行.
    • @OnMethod 声明了关注点,必须声明在公有的静态方法上public static void。静态方法为 在关注点上执行的跟踪动作
    • @TLS声明的变量是 ThreadLocal的, 每个线程都会有一份这个自己的startTime 变量
    • location: 用@Location来表明在什么时候时候去执行脚本
    • @Self 声明探测的当前对象this
    • @Return 方法返回对象

      基本实现逻辑:虚拟机其实提供了一个hook,那就是Instrumentation,可以将独立于应用程序的代理程序agent程序随着着应用程序一起启动或者attach挂载到正在运行中的应用程序。而在代理程序中可以对class进行修改或者重新定义。

  • 相关阅读:
    并发与高并发(七)-线程安全性-原子性-atomic
    并发与高并发(六)-并发模拟代码
    springboot跨域请求接口示例
    关于Java编码规范
    并发与高并发(五)-并发模拟的三个工具
    springboot整合redis简单示例
    关于码云如何检出项目
    关于自动化打包部署Jenkins的使用和配置
    针对Oracle的一系列操作
    关于Linux下Oracle安装后启动的问题
  • 原文地址:https://www.cnblogs.com/ryjJava/p/12639608.html
Copyright © 2011-2022 走看看