由于各种原因,我得出的结论是,创建定制的JVM构建可能是我尝试实现的最简单的选择,因为如果不这样做的话,太多的事情会严重影响性能。
因此,我已经启动并运行了环境,修改了一些简单的内容以生成所需的回调,并使用了一些内在函数,到目前为止效果很好。
我想知道的是:这里的JVM专家对创建具有更大对象标头(例如,多8个字节)的自定义VM的可行性有何看法。 markOop.hpp
很好地解释了标记词的内容,以适应现有的各种风格(32位,64位,带压缩的oops的64位),我想知道扩展标题以便我可以放多大的难度有关对象的一些额外信息(不选择不标记,请参阅我的帖子here)。
因此,在深入探讨这个问题之前,我希望有经验的人可以提供一些早期反馈。就像是“自杀任务”,因为到处都有太多关于标头大小和偏移量的硬编码假设的地方?还是所有这些都相当集中并且可以通过合理的努力完成而又不会冒险破坏所有内容?任何可能需要特别注意以及可能产生什么后果的指针(除了非常明显的情况;更多的内存消耗)?
答案 0 :(得分:2)
绝对有可能扩大对象标头(我以前见过这样的实验),尽管这并不像在class oopDesc中添加新字段那样容易。我相信JVM代码中有多个地方取决于对象标头的大小,但不应过多。对象标头的大小已经根据平台和UseCompressedOops
选项而有所不同,因此代码中的大多数位置已经使用了相对偏移量,并且不会出现新字段。
另一个选择不是扩展标题,而是向java.lang.Object
类添加新的假字段。 HotSpot已经具有添加此类字段的机制,请在源代码中查找InjectedField。但是,这也不是一件容易的事。系统类有一些硬编码的偏移量,请参见JavaClasses::check_offsets。这些也需要修复。
就实施工作而言,这两种方法大致相同。在这两种情况下,我都建议从debug
(而不是fastdebug
)的JVM版本开始,因为它们包括许多有用的断言,可以尽早发现可能的偏移问题。
听说您的项目,我认为您还有第三个选择:放弃“仅JVMTI”的要求,并利用字节码检测和JIT编译的功能重写Java中的代理的某些部分。是的,这可能会稍微改变正在执行的Java代码,并可能导致加载更多的类,但这真的很重要吗,如果从用户的角度来看,这种影响是否会比仅使用JVMTI的代理的影响还要小?我的意思是,当没有Java本机开关,JVMTI开销等时,对性能的影响可能会大大减少。如果代理程序的开销很低并且可以与现有的JVM一起工作,那么我想在生产环境中启用它以获得其出色功能不是什么大问题吗?