当前位置: 首页 > backend >正文

Java 探针的原理

Java 探针的原理其实核心就四个字:
字节码增强

一、Java 探针的核心机制

Java 探针一般是通过 Java Agent 技术实现的,依赖于 JVM 提供的 Instrumentation 接口。

1. Java Agent

  • JVM 启动时,可以通过 -javaagent:xxx.jar 加载一个探针 Jar 包。
  • 这个 Jar 包里需要有一个入口类,并实现 premain(String args, Instrumentation inst) 方法。
  • JVM 启动时会先调用 premain,然后再运行你的应用 main 方法。

2. Instrumentation

  • Instrumentation 提供了操作 类加载 的能力。
  • 可以注册 ClassFileTransformer,在类被加载进 JVM 时,修改它的字节码。
  • 借助 ASMJavassist 等字节码工具,就能在目标类的方法前后插入代码。

3. 探针的运行逻辑

  1. JVM 启动时加载探针 Jar。
  2. 探针注册一个 Transformer。
  3. 当某个类加载时,探针修改它的字节码(比如在方法入口/出口插入埋点)。
  4. 应用运行时,探针代码也随之运行,实现监控/拦截/增强。

二、Java 探针常见应用

  1. 性能监控 (APM)

    • 拦截 HTTP 请求方法,记录调用链。
    • 拦截 JDBC,记录 SQL 和执行时间。
    • 采集 JVM 指标(GC、内存、线程)。
  2. 安全防护 (RASP)

    • 在 Servlet 的 doFilter 拦截请求,检测 SQL 注入/XSS。
    • FileInputStreamSocket 等 API 上插入检测逻辑。
  3. 诊断工具

    • Arthas、BTrace 这些工具就是探针。
    • 在运行时动态 attach 探针,修改类行为,不用重启应用。

三、简单示例:打印方法执行时间的探针

Agent.java

import java.lang.instrument.Instrumentation;public class Agent {public static void premain(String args, Instrumentation inst) {System.out.println("Java Agent Loaded!");inst.addTransformer(new MyTransformer());}
}

MyTransformer.java(用 Javassist 修改字节码)

import java.lang.instrument.ClassFileTransformer;
import java.security.ProtectionDomain;
import javassist.*;public class MyTransformer implements ClassFileTransformer {@Overridepublic byte[] transform(ClassLoader loader, String className,Class<?> classBeingRedefined, ProtectionDomain protectionDomain,byte[] classfileBuffer) {if ("com/example/DemoService".equals(className)) {try {ClassPool pool = ClassPool.getDefault();CtClass ctClass = pool.get("com.example.DemoService");CtMethod method = ctClass.getDeclaredMethod("process");method.addLocalVariable("start", CtClass.longType);method.insertBefore("start = System.currentTimeMillis();");method.insertAfter("System.out.println(\"耗时: \" + (System.currentTimeMillis()-start) + \"ms\");");return ctClass.toBytecode();} catch (Exception e) {e.printStackTrace();}}return classfileBuffer;}
}

运行时:

java -javaagent:my-agent.jar -jar app.jar

这样 DemoService.process() 方法就会自动打印耗时。

四、总结

  • Java 探针原理 = JVM 的 Instrumentation API + 字节码增强技术

  • 关键点

    • 通过 -javaagent 在 JVM 启动时加载。
    • 修改类字节码,在方法前后插入探针逻辑。
    • 适合做性能监控、安全防护、诊断。
http://www.xdnf.cn/news/18716.html

相关文章:

  • 深入解析:为什么应该避免使用 atoi、atol 和 atof 函数
  • 《C++ Primer 第五版》省略符号(...)
  • 【小增长电商技术分享】电商支付宝批量转账工具技术测评:架构特性、合规风险与选型方法论,支付宝官方|小增长|云方付|易推客省心返
  • vi/vim 查找字符串
  • Ajax笔记(上)
  • Spark面试题
  • Redis面试精讲 Day 30:Redis面试真题解析与答题技巧
  • 南京魔数团:AR技术引领远程协作新纪元
  • Java网络编程:从入门到精通
  • STM32之DMA详解
  • 算法题记录01:
  • 8月25日
  • 专题:2025人工智能2.0智能体驱动ERP、生成式AI经济现状落地报告|附400+份报告PDF、原数据表汇总下载
  • [论文阅读]RQ-RAG: Learning to Refine Queries for Retrieval Augmented Generation
  • k8s的etcd备份脚本
  • AR技术赋能农业机械智能运维
  • 电机控制::基于编码器的速度计算与滤波::RLS
  • 【C++】第二十六节—C++11(中) | 右值引用和移动语义(续集)+lambda
  • Linux_用 `ps` 按进程名过滤线程,以及用 `pkill` 按进程名安全杀进程
  • 机器学习-大语言模型Finetuning vs. Prompting
  • 大型语言模型基准测试综述《A Survey on Large Language Model Benchmarks.pdf》核心内容总结
  • 京东前端社招面经
  • 多维度指标交叉计算查询方案
  • 【芯片后端设计的灵魂:Placement的作用与重要性】
  • 6、RocketMQ消息积压问题如何解决
  • Python爬虫实战:Selenium模拟操作爬取马蜂窝旅游攻略
  • 数据挖掘 6.1 其他降维方法(不是很重要)
  • redis----list详解
  • 深度学习入门第一课——神经网络实现手写数字识别
  • 读《精益数据分析》:A/B测试与多变量测试