JVM预热查询

7
我是一名新手Java程序员。我正在了解JVM热身,明白这指的是JVM寻找热点并对代码的这些部分进行JIT编译所需的时间。
我也知道需要运行我的测试几百次才能做到这一点。
但我不理解以下几点:
1. 在JVM完全热身之前,我应该确定测试运行的次数吗?
2. 这是否因JVM而异?我的意思是说,如果我能够通过运行1000次迭代来使我的JVM热身,那么其他人可能需要更多或更少?
3. 运行测试是热身JVM的唯一方法吗?
4. 我应该何时热身JVM?我指的是频率。每次停止和启动我的应用程序时都要这样做,还是只在重启服务器后做一次?
这是我在这里的第一个问题。我在发布前阅读了指南。如果有任何错误,请建议修改。

你在谈论什么类型的应用程序?为什么你认为需要进行预热呢?运行测试将会预热运行测试的JVM,而不是服务于你的应用程序的JVM。 - JB Nizet
你正在进行任何类型的基准测试吗? - SMA
从我所了解的JVM预热方面来看,如果我正在处理大量交易,那么如果我的JVM已经预热过了,那么处理时间会更短。我仍然在理解这些概念。我应该如何预热为我的应用程序服务的JVM呢? - user5840356
2
你很可能是在过早地进行优化。只需启动JVM,让它处理第一个真正的请求并识别热点:它很可能已经足够快了。如果确实收到大量请求,它会自行快速预热。大多数在线应用程序无论如何都不会受到CPU限制,而是受到IO限制。因此,如果一个方法在未预热时需要0.5毫秒的时间,但在任何情况下都要花费200毫秒的IO时间,那么差异将是可以忽略不计的。 - JB Nizet
@JBNizet 感谢您宝贵的意见。您能否抽出一些时间回答其他问题并发布答案,以便我可以接受呢? - user5840356
显示剩余4条评论
3个回答

4
我该如何确定在我的JVM完全预热之前应运行测试的次数?
假设您使用默认的-XX:CompileThreshold=10000,则在10,000次调用后或者在其中有一个循环迭代了10,000次后,会触发对该方法的编译。这将在后台排队进行编译,因此可能需要12K-20K次迭代才能运行优化代码。
注意:JIT可以重新优化代码,即使在10K或1百万次迭代后,您也可能看到时间变化。
这是否因JVM而异?我的意思是说,如果我能够通过运行1000次迭代来预热我的JVM,那么其他人可能需要更多或更少吗?
是的。如果您做比您认为需要的更多,则这是覆盖更多配置的最佳方式。
运行测试是预热JVM的唯一方法吗?
您应该真正运行实际代码。运行测试可以减少预热代码的影响,因此在生产中更实用。
我什么时候应该预热JVM?我的意思是频率。每次停止和启动应用程序时都应该这样做,还是只在重新启动服务器后执行一次?
每当您启动JVM时,您都是从头开始的。即使相同的JVM已经运行,或者您从另一个JVM中生成一个JVM。

@TheLostMind 分布式或非分布式,是否需要手动预热代码取决于预热前的性能是否可接受以及您是否可以在使用之前预热应用程序,即服务是否在使用之前很长时间启动。在我看来,这种情况相当罕见,但在低延迟交易系统中确实有很大帮助,因为在以最佳速度执行之前等待10,000个订单是很多的,特别是如果这些订单每个都是数百万美元,并且您经常重新启动服务器。 - Peter Lawrey
嗯,我明白了...这很有道理。我想说的是,如果你的应用程序部署在 AWS 上,每次根据负载创建新实例/ JVM,预热代码会很困难。 - TheLostMind
3
@TheLostMind,你不愿意接受的是,对于每日或每周前100亿美元的订单,你将无法获得最佳的速度/价格。一个慢速订单可能会让你的名义金额损失0.002%,听起来不像什么大不了的,但这可能是每周2万美元。 - Peter Lawrey
2
如果在需要它们之前加载实例,例如甚至提前10秒或1分钟,您可以花费这段时间来预热代码,或者至少进行一些基本的正确性测试。最大的影响是第一次加载类时,因此仅仅运行一次代码可能就足够了。 - Peter Lawrey
3
顺便说一句,热身不仅仅是关于即时编译。我会说,在大型服务器应用程序中,它根本不涉及JIT。确定热身阶段结束的唯一方法是观察特定于应用程序的性能指标趋于稳定。 - apangin
显示剩余5条评论

3
为了开始,你不必担心在生产环境中进行预热/强制编译的方法,因为让我们面对现实——JIT比我们更聪明:P。
“我应该如何确定测试运行多少次后我的JVM完全预热?”在Java 8上的Mac上,一个方法需要大约256次迭代才能被JIT编译(假设该方法可以被JIT编译)。这个数字可能因JVM而异。
“这会随着JVM的变化而改变吗?我的意思是说,如果我通过运行1000次迭代来预热我的JVM,那么其他人可能需要更多或更少吗?”这可能因JVM而异。不能安全地假设这个数字对不同的JVM保持不变。
“运行测试是预热JVM的唯一方法吗?”好的,如果你想要基准测试什么东西,那么是的。你应该让JVM优化它所能优化的内容(通过使用预热运行),然后测量性能。
“我什么时候应该预热JVM?我的意思是频率。我应该每次停止和启动应用程序时都这样做,还是只需要在重新启动服务器后执行一次?”每次你想要进行基准测试时(即,在JVM/app启动时)。我认为在生产环境中没有必要这样做。请注意,在某些情况下,如果JIT发现其假设有缺陷,它实际上可能会更喜欢解释方法而不是编译方法。

我想投票支持你的回答,但是系统不允许我这样做。 - user5840356
1
@MissMeme - 没问题Madamji :).. 您应该安装JitWatch来查看JIT正在编译什么以及经过多少次运行等等。 - TheLostMind
@ThLostMind 感谢您的回复。我将安装JitWatch。 :) - user5840356
2
我很确定在Mac上使用-XX:CompileThreshold=10000也是有效的。 - Peter Lawrey
@PeterLawrey - 是的。我刚刚检查过了。它设置为10000,但是当运行256次时,C1会以级别3编译我的一个方法 :) - TheLostMind
显示剩余6条评论

1

如何确定在我的JVM完全预热之前应运行测试的次数?

  • 测量应用逻辑的延迟和吞吐量,并查看何时达到稳定状态
  • 使用-XX:+PrintCompilation跟踪JIT行为

每个应用程序都是不同的,因此最好收集自己的数据。基于该数据,您可以做出进一步的决策。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接