假设您有一个在生产环境中运行的应用程序。每隔一段时间,它就会进入中断状态,错误很难重现,您需要从应用程序中获得更多信息。
那么你想知道解决方案吗?
您可以做的是动态地将一些代码集附加到应用程序中,并仔细地重写它,以便代码转储您可以记录的其他信息,或者您可以将应用程序阶段转储到文本文件中。Java为我们提供了使用 Java Agent 实现这一点的工具。
你有没有想过我们的Java代码是如何在IDE中进行热交换的?这是因为特工。关于Java Agent的另一个有趣的事实是,应用程序探查器在后端使用相同的技术来收集内存使用情况、内存泄漏和方法执行时间的信息。
那么什么是Java Agent呢?
Java Agent是一种特殊类型的类,通过使用Java Instrumentation API,它可以拦截JVM上运行的应用程序,修改它们的字节码。Java Agent非常强大,也非常危险。
在开始之前,我将解释Java Agent如何使用简单的HelloWorld示例拦截类。
public class Hello { public static void main(String[] args){ System.out.println("hello world"); } }
如下图所示,类加载器负责将类从二进制加载到内存中。运行编译后的HelloWorld应用程序( HelloWorld.class
)时,可以将Agent视为在运行时拦截类加载器行为的一种方式。您可能会想,java字节代码是如何被重新构造的,以便Agent可以在正确的位置添加相关代码的。有趣的是,对于Java程序来说,字节码的结构非常接近原始Java程序源代码。因此,虽然我们不为Java程序本身添加工具,但我们使用了它的一个非常接近的表示形式。需要注意的是,有一些非Java语言可以编译成Java字节码(如Scala、Clojure和Kotlin),这意味着程序字节码的结构和形状可能会非常不同。
实现Java Agent
JavaAgent基于来自Java平台的facility,它的入口点是 Java.lang instrument
包,它提供了允许Agent为JVM上