字节码以无证方式随时间变化

今天我在openjdk 7上用javaagent和instrumentation来探索大型应用程序(比如带有应用程序的jboss服务器)的类。我每隔10秒就调用所有类的重新转换,所以它们的字节码在我的ClassFileTransformer实现中得到了。

我的实现只是跟踪类的字节码如何随时间变化。 首先,我很惊讶,字段和方法的顺序,方法访问修饰符,常量池的内容和其他类似的东西因检查而异。 但是,它仍然记录在案 。

没有记录的内容 – 某些项目可以在类中创建常量池并注入到方法中。 现在我注意到数字值(Longs,Doubles,Floats等)会发生。

这是它在javap中的样子; 之前:

pool: ... #17 Float NaNf method: #1 fload #17 //NaNf ... 

在运行时更改类之后:

 pool: ... #17 Float NaNf #18 Float NaNf method: #1 fload #18 //NaNf <- look, it loads #18 now 

我仔细检查过,没有附加任何其他变压器或代理商。

为什么JVM不能让我的字节码保持不变? 我在哪里可以阅读有关此类优化/转换(或其他什么)? 我读过JVM源代码,但这些只让我更加困惑。

我只是想创建一种实时字节码validation器 – 一种安全工具。

没有记录的内容 – 某些项目可以在类中创建常量池并注入到方法中。

那么,你自己链接的文章清楚地说:

常量池可以具有更多或更少的条目。 常量池条目的顺序可以不同; 但是,方法的字节码中的常量池索引将对应。

所以它实际上是有记录的。 原因是完全记住每个类的字节码是没有用的,因此重复所有在很多类中相同的常量池条目。 JVM通常具有与普通类文件不同的内部格式,并且一旦需要就生成类文件,例如在调用变换器时。