我正在尝试为一个对延迟敏感的Java应用程序编写热身例程,以优化否则会因为动态类加载和JIT(主要原因)而减慢的前几个事务。
我面临的问题是,即使我的热身代码加载了所有的类并通过多次调用它们进行了练习(至少100次-XX:CompileThreshold),但稍后当实际用户登录时,这些相同的函数仍然被标记为“非入口”,需要重新编译,这会导致延迟问题。
JVM标志如下(我只添加了-XX:+PrintCompilation -verbose:class tp troubleshoot,其他标志是遗留的):
-Xms5g -Xmx5g -server -XX:+AggressiveHeap -XX:+UseFastAccessorMethods -XX:+PrintGCDetails -XX:CompileThreshold = 100 -XX:-CITime -XX:-PrintGC -XX:-PrintGCTimeStamps -XX:+PrintCompilation -verbose:class
#Warmup happens here
12893 2351 my.test.application.hotSpot (355 bytes)
#Real user logs on here
149755 2351 made not entrant my.test.application.hotSpot (355 bytes)
151913 2837 my.test.application.hotSpot (355 bytes)
152079 2351 made zombie my.test.application.hotSpot (355 bytes)
热身后不会发生类加载(尽管我可以看到之前有类加载,所以标记有效)。
似乎该函数获得了一个新的ID(2351与2837),这意味着JVM认为它是“不同的”。
那么我该如何确定JVM为什么要重新编译这个函数呢?
我猜这归结于如何确定为什么ID发生了变化?标准是什么?
我尝试将尽可能多的方法和类标记为私有,但没有用。
这是JRE 1.6.0_45-b06。
有关如何故障排除或获取更多信息的任何提示都将不胜感激!:)