【发布时间】:2013-09-25 15:52:18
【问题描述】:
使用自定义 java 代理打包 jar 文件时,可以添加以下属性:
Can-Redefine-ClassesCan-Retransform-Classes
这两者有什么区别?
如果在加载类之前重新定义,之后重新转换,那么重新转换究竟是什么时候发生的?
【问题讨论】:
标签: java javaagents
使用自定义 java 代理打包 jar 文件时,可以添加以下属性:
Can-Redefine-ClassesCan-Retransform-Classes这两者有什么区别?
如果在加载类之前重新定义,之后重新转换,那么重新转换究竟是什么时候发生的?
【问题讨论】:
标签: java javaagents
它们为我们提供的功能似乎几乎是多余的。主要区别似乎在于,当我们重新定义一个类时,我们会突然提供带有新定义的byte[],而当我们重新转换时,我们会得到一个byte[] 通过相同的 API 包含当前定义,我们返回修改后的 byte[]。
因此,要重新定义,我们需要更多地了解该类。考虑注入分析跟踪语句的用例。使用 retransform 您可以更直接地做到这一点:只需查看给定的字节码,修改它,然后返回它。但如果我们采用 redefine 路线,我们需要从某个地方(例如 getResourceAsStream())获取原始的 byte[]。
另一个明显的区别是我们与其他类转换器的交互方式;谁先走。变换应用于原始类或重新定义的类,因此可以添加多个变换,例如。
从历史上看,如果我们查看API documentation 或this book 的第238 页中的Since cmets(Friesen 2007 Beginning Java SE 6 Platform),我们注意到在 Java 5 中引入了 redefinition 功能,在 Java 6 中引入了 retransformation。我的猜测是 retransformation 是作为更通用的功能引入的,但为了向后兼容,必须保留重新定义。
引用上面链接的书中关于重新转换方法的关键语句:
代理使用这些方法重新转换以前加载的类 无需访问他们的类文件。
问题的第二部分:
如果重新定义发生在类加载和重新转换之前 之后,那么究竟什么时候发生重新转换?
不,在加载类以及重新转换之后会发生重新定义。它们分别在您调用 Instrumentation 实例的 redefineClasses(..) 和 retransformClasses(..) 方法时发生。
这里有一个问题要问路过的任何专家:有什么可以通过重新定义类来完成,而通过重新转换它们却无法做到的事情?我的猜测是答案是“什么都没有”。
【讨论】:
重新定义意味着代理将在任意时间点调用 Instrumentation。 redefineClasses 更改现有(和已加载)类的实际定义。代理将为新定义提供字节码。
重新转换是指类文件转换的过程,通常在类加载时应用。代理可以注册 ClassFileTransformer,它们会被一个接一个地调用,以便在类初始化之前对字节码进行转换。因此,重新转换是指 JVM 对已加载的类重复此过程的能力。在这种情况下,代理可以调用 Instrumentation.retransformClasses 指定要重新转换哪些类,但不指定字节码。相反,JVM 将调用所有已注册的能够重新转换的 ClassFileTransformers,提供实际的字节码(或链式转换器的前一个转换器的结果)。
【讨论】:
再转化:
转换是指类文件转换的过程,通常在类加载时应用。代理可以注册 ClassFileTransformer,它们会被一个接一个地调用,以便在类初始化之前对字节码进行转换。所以Retransformation是指JVM对已经加载的类重复这个过程的能力。
重新转换与检测类/方法具有相同的功能,但用于加载的类。
重新转换的问题: JVM 将字节码存储在 PermGen(Java 7 或更低版本)或 Metaspace(Java 8 或更高版本)中。每次代理重新转换类/方法时,JVM 都会将修改后的字节码的副本保存在 PermGen 或 Metaspace 中。过度的重新转换会导致内存泄漏。
IBM Java 有额外 10% 的 CPU 开销用于重新转换。这就是在 IBM Java 代理中禁用重新转换的原因。 大约 80% 的 JVM 崩溃是由于重新转换 - 这并不意味着 JVM 在大多数情况下都会崩溃,但每当我们遇到 JVM 崩溃问题时,大约 80% 的时间是因为重新转换。
禁用重新转换: 有一个 java 选项系统属性 (-Dappdynamics.agent.disable.retransformation=true) 可以禁用重新转换
【讨论】: