技术或效用最大限度地减lessJava的“热身”时间?
我支持需要低延迟(每个消息处理<300微秒)的Java消息传递应用程序。 但是,我们的分析表明,Sun Java虚拟机一开始运行缓慢,在前5000条消息之后加速。 前5,000个消息的延迟为1-4毫秒。 在大约第一个5000之后,随后的消息具有〜250微秒的延迟,偶尔出现exception值。
通常可以理解,这是Java应用程序的典型行为。 但是,从业务angular度来看,告诉客户他们必须等待JVM“预热”才能看到所需的性能,这是不可接受的。 在处理第一个客户消息之前,应用程序需要“预热”
JVM是Sun 1.6.0 Update 4。
解决这个问题的想法:
- JVM设置,如-XX:CompileThreshold =
- 添加一个组件在启动时“预热”应用程序,例如通过应用程序发送“假消息”。
- 在应用程序启动时静态加载应用程序和JDK类,以便在处理客户消息时不从JAR加载类。
- 一些实用程序或Java代理完成上述两个想法中的一个或两个,以便我不必重新发明轮子。
注意:显然,对于这个解决scheme,我正在查看所有的因素,包括芯片拱形,磁盘types和configuration以及操作系统设置。 但是,对于这个问题,我想集中讨论如何优化Java应用程序,最大限度地减less“热身”时间。
Java中的“热身”通常是两件事情:
(1):懒类加载:这可以通过强制加载来解决。
简单的方法是发送一个假消息。 你应该确保假消息将触发所有类的访问。 例如,如果你发送一个空的消息,但你的progrom会检查消息是否为空,并避免做某些事情,那么这是行不通的。
另一种方法是在程序启动时通过访问该类来强制类初始化。
(2):实时优化:在运行时,Java VM会优化部分代码。 这是为什么有一个热身时间的主要原因。
为了缓解这一点,你可以发送一堆假(但看起来真实)的消息,以便优化可以在用户使用之前完成。
另一个你可以帮助缓解这个问题的方式是支持内联,比如尽可能地使用私有和最终的方法。 原因在于,VM不需要查找inheritance表来查看实际被调用的方法。
希望这可以帮助。
你的问题不是类加载,而是“及时”编译。
试试-XX:CompileThreshold=1
这将迫使Java在第一次运行它时编译所有的东西。 它会减慢代码的启动速度,但不会影响虚拟机代码(因为安装Java时会编译代码)。 有一个问题可以让Java以类似的方式编译自定义的JAR文件,并保存后续执行的结果,这将大大减less这种开销,但是没有任何的压力来解决这个bug。
第二种select是将50000个假消息发送到应用程序以“热身”。 出售这个“确保一切正确设置”。
[编辑]预编译类中的一些背景信息: 类数据共享
您可能想尝试IBM的Java版本,因为在这里,您可以添加更多的类到共享池: 类数据共享的概述
回答kittylyst提出的问题 :这是真的,这将快速填满你的代码caching与只使用一次的方法。 它甚至可能让你的整个应用程序变慢。
如果将其设置为较低值,则应用程序的启动时间可能会变得非常慢。 这是因为运行编译代码的JIT优化+比在解释模式下运行代码更昂贵。
这里的主要问题是代码仍然是“及时”编译的。 只要你不能运行你需要的方法至less一次,应用程序每遇到一些以前没有编译过的东西,就会“唧唧喳喳”几毫秒。
但是如果你有RAM,你的应用程序很小,或者你可以增加代码caching的大小,你不介意缓慢的启动时间,你可以试试这个。 一般来说,默认设置是相当不错的。
在打开真正的客户stream量之前,只需在系统中运行一堆没有操作的消息。 10k消息是通常的数字。
对于金融应用程序(例如FIX),通常通过在开盘之前向市场发送订单(远离昨晚收盘价,以防万一)来完成。 他们都会被拒绝,但这并不重要。
如果您使用的协议是自制软件,那么下一次为其升级库时,请明确支持“WARMUP”或“TEST”或“SANITYCHECK”消息types。
当然,这可能不会编译你的应用程序逻辑特定的path,但是在一个体面的消息应用程序中,处理networkingstream量的部分几乎肯定是堆栈的主要部分,所以这并不重要。
你使用客户端还是服务器JVM? 尝试开始你的程序:
java -server com.mycompany.MyProgram
在这种模式下运行Sun的JVM时,JIT会将字节码编译为本地代码; 因此,程序启动需要更长的时间,但在此之后运行速度会更快。
参考: 有关Java HotSpot VM的常见问题
引用:
-client和-server系统有什么区别?
这两个系统是不同的二进制文件。 它们本质上是两个不同的编译器(JIT),连接到相同的运行时系统。 客户端系统适用于需要快速启动时间或占用空间小的应用程序,服务器系统最适合整体性能最为重要的应用程序。 一般来说,客户端系统更适合GUI等交互式应用程序。 其他一些差异还包括编译策略,堆默认值和内联策略。
如果在当代硬件(每个CPU有2个或更多内核)和最新版本的JDK上以Hotspot服务器模式运行,则可以使用以下选项来加速预热:
-XX:+分层编译
老线程,我知道,但我发现在互联网上:
一个非常有趣的事情是选项-XX:CompileThreshold = 1500对SUN HotSpot JVM的影响。 服务器虚拟机默认为10000,客户机虚拟机默认为1500。 但是,将服务器虚拟机设置为1500会使其比客户端VM更快。 将其设置为100会降低性能。 而使用选项-Xcomp(这意味着所有的代码在使用之前编译)给出了更低的性能,这是令人惊讶的。
现在你知道该怎么做了。
似乎你的项目将受益于实时保证:
请参阅: 实时Java