Visualvm基于NetBeans平台开发工具,具备通过插件扩展功能的能力。有了插件扩展功能,Visualvm可以做到:
生成堆转储快照有两种方式:
[heapdump]文件是临时文件,需要手动保存。手动保存的dump文件可以通过 文件 -> 装入 功能打开
在Profiler页签中,Visualvm提供了程序运行期间方法级的处理器执行时间分析和内存分析。做Profiling分析对程序运行性能有较大影响,所以一般不会在生产环境使用该功能。
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; } }
/* 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))); } }
Btrace之所以安全可靠的,是因为它对正在运行的程序是只读的。也就是说,他可以插入跟踪语句来检测和分析运行中的程序,不允许对其进行修改。因此他存在一些限制:
这些限制其实是可以使用unsafe模式绕过,通过声明 *@BTrace(unsafe = true)
annotation。实际使用非安全模式跟踪时,发现一个问题,一个进程如果被安全模式btrace探测过一次, 后面再使用非安全模式进行探测时非安全模式不生效。
基本实现逻辑:虚拟机其实提供了一个hook,那就是Instrumentation,可以将独立于应用程序的代理程序agent程序随着着应用程序一起启动或者attach挂载到正在运行中的应用程序。而在代理程序中可以对class进行修改或者重新定义。
原文:https://www.cnblogs.com/ryjJava/p/12639608.html