Java/JVM (HotSpot):有没有办法在编译时节省 JIT 性能增益?
当我测量 Java 应用程序的吞吐量时,我发现随着时间的推移,性能提高了 50%:
- 对于前 100K 消息,我每秒收到约 3,000 条消息
- 对于第二个 100K 消息,我每秒收到约 4,500 条消息。
我相信随着 JIT 优化执行路径,性能会提高。
不保存 JIT 编译的原因是“JVM 执行的优化不是静态的,而是动态的,基于数据模式和代码模式。很可能这些数据模式将在应用程序的生命周期内发生变化,从而使缓存的优化效果达不到最佳效果。”
然而,我知道一个事实是,这些数据模式在我的应用程序的生命周期内,甚至在多个应用程序的生命周期内都不会改变。那么如何才能在 HotSpot JVM 中“保存”这些性能提升呢?
When I measure the throughput of my Java application, I see a 50% performance increase over time:
- For the first 100K messages, I get ~3,000 messages per second
- For the second 100K messages, I get ~4,500 messages per second.
I believe the performance improves as JIT optimizes the execution path.
The reason given for not saving the JIT compilation is that "the optimizations that the JVM performs are not static, but rather dynamic, based on the data patterns as well as code patterns. It's likely that these data patterns will change during the application's lifetime, rendering the cached optimisations less than optimal."
However, I know for a fact that these data patterns won't change during my application's lifetime, or even over multiple application lifetimes. So how can I "save" these performance gains in the HotSpot JVM?
See also, the relevant question and discussion.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您可以尝试调整您的应用程序以使用 Nailgun 运行它。每次您针对 Nailgun 服务器调用您的应用程序(这是一个长期存在的 JVM)时,您不必针对新的 JVM 调用您的应用程序。第二次调用应用程序时,钉枪 JVM 将优化类中的路径,因此执行速度应该比刚开始时快得多。
You could try adapting your app to run it with Nailgun. Instead of invoking your app against a fresh JVM each time you invoke it against a Nailgun server which is a long-lived JVM. The second time you invoke your app, the nailgun JVM will have optimized the paths in your classes and should therefore execute a lot faster than it would from fresh.
使用“-server”可以预先完成更多操作。据我所知,Hotspot 不允许在运行之间保存 jit 信息,因此 -server 是告诉它你想要它做什么的最简单方法。
Use '-server' to do much more up front. Hotspot does not as far as I know allow for saving jit information between runs so -server is the simplest way to tell it what you want it to do.
你确定是CPU相关而不是IO相关吗?我已经多次看到这种行为,当在某个地方命中冷缓存时,性能会恶化。
Are you sure it is CPU related and not IO related? I have seen this behaviour a lot of times, when hitting a cold cache somewhere worsens performance.
几乎没有其他选项可以调整 JIT。
1.班级数据共享
http://publib.boulder.ibm.com/infocenter/javasdk/v6r0/index.jsp?topic=%2Fcom.ibm.java.doc.user.aix64.60%2Fuser%2Fclassdatasharing.html
2.分层编译
查看标志 -XX:+TieredCompilation
3 的详细信息。自定义编译阈值
控制函数的调用次数,使其符合 JIT 编译条件。
请参阅标志 -XX:CompileThreshold 的详细信息。切勿将其设置为 0 或 1。您在此处的篡改可能会导致性能下降。不过 JVM 给了你这个选择。 -server 默认值为 10000。
Few more options to tune up the JIT.
1. Class Data sharing
http://publib.boulder.ibm.com/infocenter/javasdk/v6r0/index.jsp?topic=%2Fcom.ibm.java.doc.user.aix64.60%2Fuser%2Fclassdatasharing.html
2. Tiered Compilation
See details for flag -XX:+TieredCompilation
3. Custom CompileThreshold
Controls number of invocations of a function that would make it eligible for JIT compile.
See details for flag -XX:CompileThreshold. Never make this to ZERO or ONE. Your tampering here may result in deterioration of performance. JVM gives you the option though. -server defaults this to 10000.