【发布时间】:2013-08-19 20:02:14
【问题描述】:
今天我在我的 openjdk 7 上使用 javaagent 和检测来探索大型应用程序的类(例如带有应用程序的 jboss 服务器)。我每 10 秒对所有类调用一次重新转换,因此它们的字节码进入了我的 ClassFileTransformer 实现。
我的实现只是跟踪类的字节码如何随时间变化。首先,我很惊讶,字段和方法的顺序、方法访问修饰符、常量池的内容和其他诸如此类的事情因一项检查而异。但是,它仍然是documented。
未记录的内容 - 某些项目可能会在类的常量池中创建并注入方法中。现在我注意到数值(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 源代码,但这些只会让我更加困惑。
我只是想创建某种实时字节码验证器 - 一种安全工具。
【问题讨论】:
-
没有什么说生成的代码必须是确定性的,只要代码的效果是确定性的。毫无疑问,许多差异的出现是因为每次运行时事物都会散列到不同的桶中。
-
抱歉,我不了解存储桶。你指的是什么桶?顺便说一句,没有生成该代码。它被编译,放入罐子中并且一直保持不变。
-
你有任何正在改变字节码的转换器吗?
-
@Antimony No. 我的返回null,没有其他附加。
-
存储在文件系统中的.class文件中的代码不会改变,除非你改变它。但是根据定义,转换器会更改类文件的存储映像。