0

0

如何搭建Java的动态追踪环境_BTrace脚本监控Java运行状态

P粉602998670

P粉602998670

发布时间:2026-03-18 10:51:15

|

524人浏览过

|

来源于php中文网

原创

BTrace脚本不生效的根本原因是JVM未启用调试支持或版本不兼容;需确认启动参数、JDK匹配、沙箱限制及正确使用@OnMethod等。

如何搭建java的动态追踪环境_btrace脚本监控java运行状态

为什么 BTrace 脚本没生效,连 println 都不输出?

根本原因通常是 JVM 启动时没开调试支持,或者 BTrace 版本和 JDK 不兼容。BTrace 依赖 -javaagent 和 JVMTI 接口,JDK 9+ 默认禁用部分 JVMTI 功能,且 OpenJDK 17+ 已移除对 BTrace 的原生支持。

  • 确认 JVM 启动参数包含 -XX:+UnlockDiagnosticVMOptions -XX:+AllowEnhancedClassRedefinition(JDK 8 必加;JDK 11+ 可能还需 --add-exports java.base/jdk.internal.vm=ALL-UNNAMED
  • BTrace 2.x 仅支持 JDK 8~11;JDK 17+ 基本不可用,别硬试——会静默失败,无日志、无报错
  • BTraceRunner 必须用与目标 JVM 相同的 JDK 运行,混用 JRE/JDK 或不同厂商(如 Zulu vs. Temurin)会导致 ClassNotFoundException
  • 脚本里避免调用任意非 java.lang.* 外部类,BTrace 沙箱禁止加载第三方类,否则直接跳过织入

如何写一个安全可用的 @OnMethod 监控脚本?

BTrace 的核心是静态字节码注入,不是代理或 AOP,所以方法签名必须完全匹配,且不能修改原逻辑。稍有偏差就织入失败,还查不到原因。

  • 目标类名必须写全限定名,比如 "java.util.ArrayList",不能写 "ArrayList";内部类用 $ 分隔,如 "com.example.Service$Inner"
  • @OnMethodclazzmethod 是必填项,location = @Location(Kind.RETURN) 才能取到返回值,但注意:返回值为 void@Return 参数会报错
  • 只允许用 print/println 输出,且输出内容必须是字符串拼接或基本类型,不能调用 toString()(可能触发新对象分配,被沙箱拦截)
  • 示例:监控 HashMap.get 调用耗时
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;

@BTrace
public class HashMapGetTracer {
    @OnMethod(
        clazz = "java.util.HashMap",
        method = "get",
        location = @Location(Kind.RETURN)
    )
    public static void onGet(@Self Object self, String key, @Return Object result) {
        println(strcat("get(", strcat(str(key), "): ")));
        println(str(result));
    }
}

BTrace 和 Arthas、JFR 对比时该选哪个?

不是“哪个更好”,而是“哪个不崩”。BTrace 在生产环境已属高危操作,尤其 JDK 11+ 后几乎退场。

AIPURE
AIPURE

AIPURE帮您轻松找到2024年最佳AI工具

下载
  • BTrace:零依赖、纯 agent,但稳定性差,JDK 升级后极易失效;适合 JDK 8 下临时排查,不建议集成进监控体系
  • Arthaswatch/trace 命令更友好,支持 JDK 8~21,热更新脚本、可卸载,出问题 kill session 就行,日常诊断首选
  • JFR(Java Flight Recorder):JDK 自带,低开销,适合长期采集 GC、锁、方法采样等,但无法自定义逻辑,也不能改行为
  • 真实场景中,BTrace 常被误用于“想改点东西”,比如想记录某个字段值——这超出它能力边界,该换 Byte BuddyJava Agent 自研

运行 btrace 命令时提示 NoClassDefFoundError: sun/jvm/hotspot/HotSpotAgent

这是 BTrace 试图用 SA(Serviceability Agent)attach 本地进程导致的,SA 在 JDK 9+ 中默认关闭,且需要额外 debuginfo 支持,基本不可用。

立即学习Java免费学习笔记(深入)”;

  • 不要用 btrace <pid> script.java 直连本地进程,改用 btracec 编译 + btrace 加载 agent 方式
  • 编译命令:btracec -d /tmp/classes MyScript.java;加载命令:btrace -p 2020 <pid> /tmp/classes/MyScript.class-p 指定端口,避免权限问题)
  • 如果目标 JVM 启用了 -XX:+DisableAttachMechanism,BTrace 完全无法 attach,需重启 JVM 并去掉该参数
  • Linux 下若提示 Permission denied,检查 /proc/sys/kernel/yama/ptrace_scope 是否为 0;非 root 用户 attach 需设为 0 或改用同一用户启动目标 JVM
BTrace 的最大陷阱不是语法难,而是它让你误以为“还能这么搞”,实际在现代 JDK 上,一次成功的织入背后全是版本妥协和参数堆砌。真要动态追踪,优先看 Arthas 的 trace,它报错清楚、能撤回、不崩 JVM——BTrace 留给离线复现和 JDK 8 遗留系统更稳妥。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
python中print函数的用法
python中print函数的用法

python中print函数的语法是“print(value1, value2, ..., sep=' ', end=' ', file=sys.stdout, flush=False)”。本专题为大家提供print相关的文章、下载、课程内容,供大家免费下载体验。

193

2023.09.27

python print用法与作用
python print用法与作用

本专题整合了python print的用法、作用、函数功能相关内容,阅读专题下面的文章了解更多详细教程。

19

2026.02.03

session失效的原因
session失效的原因

session失效的原因有会话超时、会话数量限制、会话完整性检查、服务器重启、浏览器或设备问题等等。详细介绍:1、会话超时:服务器为Session设置了一个默认的超时时间,当用户在一段时间内没有与服务器交互时,Session将自动失效;2、会话数量限制:服务器为每个用户的Session数量设置了一个限制,当用户创建的Session数量超过这个限制时,最新的会覆盖最早的等等。

337

2023.10.17

session失效解决方法
session失效解决方法

session失效通常是由于 session 的生存时间过期或者服务器关闭导致的。其解决办法:1、延长session的生存时间;2、使用持久化存储;3、使用cookie;4、异步更新session;5、使用会话管理中间件。

776

2023.10.18

cookie与session的区别
cookie与session的区别

本专题整合了cookie与session的区别和使用方法等相关内容,阅读专题下面的文章了解更详细的内容。

97

2025.08.19

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

761

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

221

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1571

2023.10.24

Python WebSocket实时通信与异步服务开发实践
Python WebSocket实时通信与异步服务开发实践

本专题聚焦 Python 在实时通信场景中的开发实践,系统讲解 WebSocket 协议原理、长连接管理、消息推送机制以及异步服务架构设计。内容包括客户端与服务端通信实现、连接稳定性优化、消息队列集成及高并发处理策略。通过完整案例,帮助开发者构建高效稳定的实时通信系统,适用于聊天应用、实时数据推送等场景。

3

2026.03.18

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 4.5万人学习

C# 教程
C# 教程

共94课时 | 11.5万人学习

Java 教程
Java 教程

共578课时 | 83.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号