最小化Java的技术或实用程序;“热身”;时间

最小化Java的技术或实用程序;“热身”;时间,java,performance,messaging,Java,Performance,Messaging,我支持的Java消息传递应用程序要求低延迟(处理每条消息的时间小于300微秒)。然而,我们的分析表明,Sun Java虚拟机起初运行缓慢,在收到大约5000条消息后运行速度加快。前5000条消息的延迟为1-4毫秒。大约在前5000次之后,后续消息的延迟约为250微秒,偶尔会出现异常值 一般认为,这是Java应用程序的典型行为。但是,从业务的角度来看,告诉客户他们必须等待JVM“预热”,然后才能看到所需的性能是不可接受的。在处理第一条客户消息之前,需要对应用程序进行“预热” JVM是Sun 1.6

我支持的Java消息传递应用程序要求低延迟(处理每条消息的时间小于300微秒)。然而,我们的分析表明,Sun Java虚拟机起初运行缓慢,在收到大约5000条消息后运行速度加快。前5000条消息的延迟为1-4毫秒。大约在前5000次之后,后续消息的延迟约为250微秒,偶尔会出现异常值

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

JVM是Sun 1.6.0更新4

克服这一问题的想法:

  • JVM设置,例如-XX:CompileThreshold=
  • 在启动时添加一个组件来“预热”应用程序,例如通过应用程序发送“假消息”
  • 在应用程序启动时静态加载应用程序和JDK类,以便在处理客户消息时不会从JAR加载类
  • 一些实用工具或Java代理可以实现上述两个想法中的一个或两个,这样我就不必重新发明轮子了

  • 注意:显然,对于这个解决方案,我考虑了所有因素,包括芯片架构、磁盘类型、配置和操作系统设置。但是,对于这个问题,我想重点讨论如何优化Java应用程序并最大限度地减少“预热”时间。

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

    尝试
    -XX:CompileThreshold=1

    这将迫使Java在第一次运行时编译所有内容。它会在某种程度上降低代码的启动速度,但不会降低VM代码的启动速度(因为安装Java时会编译VM代码)。有一个漏洞允许Java以类似的方式编译自定义JAR,并将结果保存到以后的执行中,这将大大减少此开销,但没有压力在短期内修复此漏洞

    第二种选择是向应用程序发送5000条假消息以“预热”。将此作为“确保一切设置正确”进行销售

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

    您可能希望尝试IBM版本的Java,因为在这里,您可以向共享池添加更多类:

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

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

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


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

    您使用的是客户机还是服务器JVM?尝试用以下方法启动您的程序:

    java -server com.mycompany.MyProgram
    
    在这种模式下运行Sun的JVM时,JIT会更早地将字节码编译为本机代码;正因为如此,程序将需要更长的时间启动,但之后运行速度会更快

    参考:

    引述:

    客户端和服务器系统之间有什么区别?

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

    Java中的“预热”通常涉及两件事:

    (1) :惰性类加载:可以通过强制加载来解决此问题

    要做到这一点,最简单的方法是发送假消息。您应该确保假消息将触发对类的所有访问。对于exmaple,如果您发送一条空消息,但您的程序将检查消息是否为空,并避免执行某些操作,那么这将不起作用

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

    (2) :实时优化:在运行时,JavaVM将优化部分代码。这是有热身时间的主要原因

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

    另一个可以帮助简化的方法是支持内联,比如尽可能多地使用private和final。原因是,VM不需要查找继承表来查看实际要调用的方法


    希望这能有所帮助。

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


    请参阅:

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

    -server -XX:+TieredCompilation -服务器-XX:+分层编译
    在系统为真正的客户流量开放之前,只需在系统中运行一堆禁止操作的消息。10k消息是通常的数字

    对于金融应用程序(如FIX),这通常是通过向市场发送订单(价格远离昨晚收盘价,以防万一)来实现的