我支持需要低延迟(每条消息处理300微秒)的Java消息传递应用程序。但是,我们的分析显示Sun Java虚拟机最初运行缓慢,并且在前5,000条消息之后加速。前5,000条消息的延迟为1-4毫秒。在大约前5000个后,后续消息的延迟约为250微秒,偶尔会有异常值。
通常理解这是Java应用程序的典型行为。但是,从业务角度来看,告诉客户他们必须等待JVM“热身”才能看到他们所要求的性能是不可接受的。在处理第一个客户消息之前,应用程序需要“预热”
JVM是Sun 1.6.0 update 4。
克服这个问题的想法:
注意:显然,对于这个解决方案,我正在考虑所有因素,包括芯片拱,磁盘类型和配置以及操作系统设置。但是,对于这个问题,我想集中讨论如何优化Java应用程序并最大限度地减少“预热”时间。
答案 0 :(得分:31)
(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