- 921. Minimum Add to Make Parentheses Valid 使括号有效的最少添加
- 915. Partition Array into Disjoint Intervals 分割数组
- 932. Beautiful Array 漂亮数组
- 940. Distinct Subsequences II 不同的子序列 II
BTrace 是一个动态安全的 Java 追踪工具,它通过向运行中的 Java 程序植入字节码文件,来对运行中的 Java 程序热更新,方便的获取程序运行时的数据信息,并且,保证自己的消耗特别小,大部分情况下不会影响 Java 程序的性能。
相信每一位开发都或多或少的干过这档子事:为了解决线上的一个 bug,不得不在代码中打印下入参、出参数据,然后再重启服务器,观察日志。BTrace 的出现就是为了解决这类事宜,BTrace 的最大好处,是可以通过自己编写的脚本,获取应用的一切调用信息,而不需要不断的修改代码,然后重启应用。
以下是BTrace 的一些典型应用场景:
下载最新的 BTrace releases 版本:https://github.com/btraceio/btrace/releases
解压文件夹,在 <BTRACE_HOME>/bin 目录下主要有两个命令:一个是 btrace,一个是 btracec。
BTRACE_HOME/bin/btrace PID <trace_script>
btrace 将通过 JVM Attach API 连接到 的 java 应用程序,然后把脚本绑定到应用进程,进行 AOP 式的代码植入。
BTRACE_HOME/bin/btracec <trace_script>
类似于javac,btracec 命令是用来预编译脚本的,以此校验脚本语法的正确性,要不然等运行到线上才发现写错就尴尬了。
写到这里,唯一能阻碍我们继续下去的,就是怎么写 BTrace 脚本了。
首先,推荐在集成工具(IDEA、Eclipse)中编写 BTrace 脚本,引入 BTrace 的依赖:
<dependency>
<groupId>com.sun.tools.btrace</groupId>
<artifactId>btrace-agent</artifactId>
<version>1.2.3</version>
<type>jar</type>
<scope>system</scope>
<systemPath>D:\btace\libs\btrace-agent.jar</systemPath>
</dependency>
<dependency>
<groupId>com.sun.tools.btrace</groupId>
<artifactId>btrace-boot</artifactId>
<version>1.2.3</version>
<type>jar</type>
<scope>system</scope>
<systemPath>D:\btace\libs\btrace-boot.jar</systemPath>
</dependency>
<dependency>
<groupId>com.sun.tools.btrace</groupId>
<artifactId>btrace-client</artifactId>
<version>1.2.3</version>
<type>jar</type>
<scope>system</scope>
<systemPath>D:\btace\libs\btrace-client.jar</systemPath>
</dependency>
先来看一个简单的 Demo 示例:
@BTrace//表示这是一个BTrace跟踪脚本
public class Hello {
@OnMethod(clazz = "org.jvm.demo.chapter4.btrace.BtraceCase", // 全类名
method = "add", // 方法名
location = @Location(Kind.RETURN) // 表示跟踪某个类的某个方法,位置为方法返回处
)
public static void run(@Self Object self, int a, int b, // 入参,按顺序定义
@Return int result, // 出参
@Duration long time // 方法耗时
) {
BTraceUtils.print("打印入参, a = " + a + ",b=" + b);
BTraceUtils.print("打印出参, result = " + result);
BTraceUtils.print("打印耗时,time = " + time);
}
}
btrace.bat 4284 src/main/java/org/jvm/demo/chapter4/btrace/Hello.java
BTrace 主要有两类注解需要学习,一类是探测方法的注解,像上面的 @OnMethod 注解,类似的还有 @OnTimer、@OnError、@OnExit、@OnEvent、@OnLowMemory、@OnProbe 等等;另一类是探测方法参数的注解,像上面的 @Return、@Duration、@Self,类似的还有 @ProbeMethodName、@ProbeClassName、@TargetInstance、@TargetMethodOrField 等等
本文不过分说明 BTrace 的语法,私以为平常遇到什么样的业务场景,边学边用就是了,以下是官方的一些 BTrace 资料:
由于BTrace 的安全和性能考虑,一般情况下不允许在探查方法中调用 BTraceUtils 以外的其它方法,但可使用 unsafe 模式。
BTrace 植入过的代码,会一直在,直到应用重启为止。所以即使 Btrace 退出了,业务函数每次执行时都会多出一次 Btrace 是否 Attach 状态的判断。
为了保证程序的安全,BTrace对编写的脚本进行了一些限制,比如不允许在脚本中创建对象,不允许在脚本中抛出异常等,更详细的限制请参考 BTrace 使用限制。
推荐阅读:
1、 Btrace入门到熟练小工完全指南;
2、 [如何在生产环境使用Btrace进行调试][Btrace1];
3、 [BTrace使用小结][BTrace1];
使用 btrace,我想测试我的函数使用了多少堆,所以我写: 上面的代码是我使用的 btrace 示例。 操作我的函数两次,我得到了两个不同的结果: 如图所示,堆成本不同:一个是另一个的两倍。 最佳答
我知道 BTrace 可以跟踪 java 程序的任何目标方法。但是,我想知道它是否可以跟踪代码中直接定义的方法。就像按钮监听器方法一样,因为我想跟踪这个事件。 button1.addActionLis
BTrace 文档中提到 BTrace 在空闲时几乎没有开销。这是否意味着 BTrace 仅在满足某些探测并正在处理时才有开销? 此外,当处理 Probe 时,它会占用一些 CPU 来进行处理。但
因此,我向自己介绍了 btrace,但目前我没有从中得到任何输出。使用此脚本: 包 com.sun.btrace.samples; import com.sun.btrace.annotations.
在下面的代码中: import static com.sun.btrace.BTraceUtils.*; import com.sun.btrace.annotations.*; import org
有谁知道如何运行多个btrace同时编写脚本?我不想用它们预编译并启动我的程序。我想使用多个 btrace 脚本插入正在运行的进程。 最佳答案 安装了 BTrace 插件 (http://kenai.
我正在尝试使用 BTrace 来查找某个类型何时在我的程序中首次实例化(Eclipse 调试器无法找到它),因为我看到了一些奇怪的行为(Javolution XMLStreamWriterImpl 以
我关注 btrace脚本。我想记录特定类中函数的进入和退出。 .. package com.sun.btrace.samples; import com.sun.btrace.BTraceUtils;
BTrace 是什么? BTrace 是一个动态安全的 Java 追踪工具,它通过向运行中的 Java 程序植入字节码文件,来对运行中的 Java 程序热更新,方便的获取程序运行时的数据信息,并且,
我正在使用 BTrace 1.2 并遵循 BTrace website 中的用户指南。我在使用命令运行程序时使用 BTrace 没有任何问题: btrace AllMethods.class 但是当
我想在堆栈跟踪的每一行前加上一个字符串。 有没有办法用 btrace 中的其他内容替换字符串中的所有模式? 最佳答案 这在 BTrace 中确实不支持。 您有两种可能性 - 您可以打开 不安全 模式及
VisualVM 支持执行不安全的 BTrace 脚本 ( https://kenai.com/projects/btrace/pages/UserGuide )。是否可以使用不安全的 BTrace
我只找到了一种可以提供所有 Activity 线程数量的方法: BTraceUtils.threadCount() 但是如何获取 ID 呢?我想知道调用方法 (@OnMethod) 时哪些线程处于 A
我正在使用 btrace 分析应用程序并面临限制。我尝试获取当前 java.lang.Thread 的名称。通常你可以调用 getName() 但它在 btrace 脚本中是被禁止的(任何调用异常 B
当我运行这个简单的 Java8 程序时 package test; public class TraceInt { public static void main(String args[]) thr
查看方法“methodExit”。参数“@Duration long time”中保存的时间单位是什么? package com.sun.btrace.samples; import com.sun.
我是一名优秀的程序员,十分优秀!