14

When packing a jar file with custom java agent, you can add the following properties:

  • Can-Redefine-Classes
  • Can-Retransform-Classes

What is the difference between those two?

If redefinition happens before class is loaded and retransformation after, then when does exactly retransformation happen?

4

3 回答 3

13

它们为我们提供的功能似乎几乎是多余的。主要区别似乎在于,当我们重新定义一个类时,我们突然为 abyte[]提供了新定义,而当我们retransform时,我们通过相同的 API 获得byte[]包含当前定义的 a,然后返回一个 modified byte[]

因此,要重新定义,我们需要更多地了解类。考虑注入分析跟踪语句的用例。使用retransform,您可以更直接地做到这一点:只需查看给定的字节码,修改它,然后返回它。但是如果我们走重新定义路线,我们需要byte[]从某个地方(比如getResourceAsStream())获取原始文件。

另一个明显的区别是我们如何与其他类转换器交互。谁先走。变换应用于原始类或重新定义的类,因此可以添加多个变换,例如。

从历史上看,如果我们查看API 文档中的注释或本书的第 238 页(Friesen 2007开始 Java SE 6 平台),我们注意到重定义功能是在 Java 5 中引入的,而在 Java 6 中是重新转换的。我的猜测是重新转换是作为一种更通用的功能引入的,但为了向后兼容,必须保留重新定义。

引用上面链接的书中关于重新转换方法的关键语句:

代理使用这些方法重新转换以前加载的类,而无需访问它们的类文件。


问题的第二部分:

如果重新定义发生在加载类之前并在之后重新转换,那么重新转换究竟是什么时候发生的?

不,在加载类以及重新转换之后会发生重新定义。它们分别在您调用Instrumentation实例redefineClasses(..)retransformClasses(..)方法时发生。

这是向任何路过的专家提出的一个问题:有什么可以通过重新定义类来完成,而通过重新转换它们却无法做到?我的猜测是答案是“没有”。

于 2016-08-27T05:13:54.270 回答
8

重新定义意味着代理将在任意时间点调用 Instrumentation。redefineClasses 更改现有(和已加载)类的实际定义。代理将为新定义提供字节码。

重新转换是指类文件转换的过程,通常在类加载时应用。代理可以注册 ClassFileTransformer,它们会被一个接一个地调用,以便在类初始化之前对字节码进行转换。因此,重新转换是指 JVM 对已加载的类重复此过程的能力。在这种情况下,代理可以调用​​ Instrumentation.retransformClasses 指定要重新转换哪些类,但不指定字节码。相反,JVM 将调用所有已注册的能够重新转换的 ClassFileTransformers,提供实际的字节码(或链式转换器的前一个转换器的结果)。

于 2014-04-04T08:51:00.693 回答
0

重新转换:

转换是指类文件转换的过程,通常在类加载时应用。代理可以注册 ClassFileTransformer,它们会被一个接一个地调用,以便在类初始化之前对字节码进行转换。因此,重新转换是指 JVM 对已加载的类重复此过程的能力。

重新转换与检测类/方法具有相同的功能,但用于加载的类。

Retransformation 的问题:JVM 将字节码存储在 PermGen(Java 7 或更低版本)或 Metaspace(Java 8 或更高版本)中。每次代理重新转换类/方法时,JVM 都会将修改后的字节码的副本保存在 PermGen 或 Metaspace 中。过度的重新转换会导致内存泄漏。

IBM Java 有额外 10% 的 CPU 开销用于重新转换。这就是在 IBM Java 代理中禁用重新转换的原因。大约 80% 的 JVM 崩溃是由于重新转换 - 这并不意味着 JVM 大部分时间都崩溃了,但是每当我们遇到 JVM 崩溃问题时,大约 80% 的时间是因为重新转换。

Disable Retransformation:有一个java选项系统属性(-Dappdynamics.agent.disable.retransformation=true)来禁用retransformation

于 2020-12-11T06:46:20.230 回答