减少Java“预热”时间的技术或实用程序?

时间:2009-09-26 18:31:28

标签: java performance messaging

我支持需要低延迟(每条消息处理300微秒)的Java消息传递应用程序。但是,我们的分析显示Sun Java虚拟机最初运行缓慢,并且在前5,000条消息之后加速。前5,000条消息的延迟为1-4毫秒。在大约前5000个后,后续消息的延迟约为250微秒,偶尔会有异常值。

通常理解这是Java应用程序的典型行为。但是,从业务角度来看,告诉客户他们必须等待JVM“热身”才能看到他们所要求的性能是不可接受的。在处理第一个客户消息之前,应用程序需要“预热”

JVM是Sun 1.6.0 update 4。

克服这个问题的想法:

  1. JVM设置,例如-XX:CompileThreshold =
  2. 添加组件以在启动时“预热”应用程序,例如通过应用程序发送“假消息”。
  3. 在应用程序启动时静态加载应用程序和JDK类,以便在处理客户消息时不从JAR加载类。
  4. 完成上述两个想法中的一个或两个的一些实用程序或Java代理,这样我就不必重新发明轮子了。
  5. 注意:显然,对于这个解决方案,我正在考虑所有因素,包括芯片拱,磁盘类型和配置以及操作系统设置。但是,对于这个问题,我想集中讨论如何优化Java应用程序并最大限度地减少“预热”时间。

7 个答案:

答案 0 :(得分:31)

Java中的“热身”通常有两件事:

(1):懒惰类加载:这可以通过强制加载来解决。

这样做的简单方法是发送虚假消息。您应该确保虚假消息将触发对类的所有访问。例如,如果您发送一条空消息但您的progrom将检查该消息是否为空并且避免做某些事情,那么这将无效。

另一种方法是在程序启动时通过访问该类来强制进行类初始化。

(2):实时优化:在运行时,Java VM将优化代码的某些部分。这就是为什么有一个预热时间的主要原因。

为了简化这一过程,您可以发送大量虚假(但看起来真实)的消息,以便在用户使用之前完成优化。

您可以帮助缓解此问题的另一个方法是支持内联,例如尽可能多地使用私有和最终版本。原因是,VM不需要查找继承表来查看实际调用的方法。

希望这有帮助。

答案 1 :(得分:14)

您的问题不是类加载,而是“及时”编译。

尝试-XX:CompileThreshold=1

这将迫使Java在第一次运行时编译所有内容。它会稍微减慢代码的启动速度,但不会减慢VM代码(因为在安装Java时会编译)。有一个bug允许Java以类似的方式编译自定义JAR并保存结果以便以后执行,这将大大减少这种开销,但是没有压力可以很快修复这个bug。

第二种选择是向应用程序发送5'000条虚假消息以“加热”。卖这个“确保一切都设置正确”。

[编辑]预编译类中的一些背景信息:Class Data Sharing

您可能想尝试使用IBM的Java版本,因为您可以在此处添加更多类:Overview of class data sharing

[EDIT2] 回答kittylyst提出的问题:这确实很快就会使用只使用过一次的方法来填充代码缓存。它甚至可能使你的整个应用程序变慢。

如果将其设置为较低值,则应用程序的启动时间会变得非常慢。这是因为JIT优化+运行编译代码比在解释模式下运行代码更昂贵。

这里的主要问题是代码仍然“及时”编译。只要你不能运行至少需要一次的每个方法,每次遇到以前没有编译过的东西时,app都会“hickup”几毫秒。

但是如果你有RAM,你的应用程序很小,或者你可以增加代码缓存的大小,你不介意启动时间慢,你可以尝试一下。通常,默认设置非常好。

答案 2 :(得分:6)

在打开真正的客户流量之前,只需在系统中运行一堆无操作消息。 10k消息是通常的数字。

对于财务应用程序(例如FIX),这通常是通过在打开之前向市场发送订单(价格远离昨晚收盘,以防万一)来完成的。他们都会被拒绝,但这没关系。

如果您使用的协议是自制程序,那么下次为其升级库时,请添加对“WARMUP”或“TEST”或“SANITYCHECK”消息类型的显式支持。

当然,这可能不会编译您的特定于应用程序逻辑的路径,但在一个体面的消息传递应用程序中,处理网络流量的部分几乎肯定会成为堆栈的主要部分,因此不会物。

答案 3 :(得分:3)

您使用的是客户端还是服务器JVM?尝试使用以下命令启动程序:

java -server com.mycompany.MyProgram

在此模式下运行Sun的JVM时,JIT会先将字节码编译为本机代码;因此,程序启动需要更长的时间,但之后运行速度会更快。

参考:Frequently Asked Questions About the Java HotSpot VM

引用:

  

-client和-server系统之间有什么区别?

     

这两个系统是不同的二进制文件。它们本质上是两个不同的编译器(JIT),它们连接到同一个运行时系统。客户端系统最适合需要快速启动时间或占用空间小的应用程序,服务器系统最适合整体性能最重要的应用程序。通常,客户端系统更适合GUI等交互式应用程序。其他一些差异包括编译策略,堆默认值和内联策略。

答案 4 :(得分:3)

如果在当前硬件(每个CPU有2个或更多内核)和最新版本的JDK上以Hotspot的服务器模式运行,则可以使用以下选项来加速预热:

-server -XX:+TieredCompilation

答案 5 :(得分:2)

旧线程,我知道,但我在互联网上找到了这个:

  

一个非常有趣的事情是选项-XX:CompileThreshold = 1500对SUN HotSpot JVM的影响。服务器VM的默认值为10000,客户端VM的默认值为1500。但是,对于Server VM,将其设置为1500会使其比Client VM更快。将其设置为100会降低性能。使用option-Xcomp(这意味着在使用之前编译所有代码)可以提供更低的性能,这是令人惊讶的。

现在你知道该怎么做了。

答案 6 :(得分:-4)

似乎您的项目将受益于实时保证:

请参阅:Real Time Java