linux中的Java进程需要初始预热

linux中的Java进程需要初始预热,java,linux,multithreading,Java,Linux,Multithreading,我们在RHEL6.5上有一个传统的java多线程进程,它对时间非常关键(低延迟),每天处理数十万条消息。它运行在一台功能强大的Linux机器上,拥有40CPU。我们发现,当处理前50k条消息时,该过程的平均延迟为10ms/msg,在这段“预热”时间之后,延迟开始下降,并变为7ms左右,然后是5ms,最终在每天结束时以3-4ms/s左右的速度停止 这让我感到困惑,我能想到的一个可能性是,地图在开始时会被调整大小,直到它达到一个非常大的容量——而且它不会再超过负载系数。从我所看到的情况来看,映射不是

我们在RHEL6.5上有一个传统的java多线程进程,它对时间非常关键(低延迟),每天处理数十万条消息。它运行在一台功能强大的Linux机器上,拥有40CPU。我们发现,当处理前50k条消息时,该过程的平均延迟为10ms/msg,在这段“预热”时间之后,延迟开始下降,并变为7ms左右,然后是5ms,最终在每天结束时以3-4ms/s左右的速度停止

这让我感到困惑,我能想到的一个可能性是,地图在开始时会被调整大小,直到它达到一个非常大的容量——而且它不会再超过负载系数。从我所看到的情况来看,映射不是用初始容量初始化的——所以我说可能是这样。我试图通过profiler把它放进去,并在里面输入数百万条消息,希望看到一些来自java集合的“resize”方法,但我找不到任何一个。这可能是因为我在寻找错误的东西,或者寻找错误的方向。作为一名新加入者和现有的团队成员,我试图看看是否还有其他我没有想到的原因

我能想到的另一种可能性是与内核设置相关的,但我不确定它可能是什么

我不认为这是一个编程逻辑问题,因为它在第一个30k-50k消息之后以可接受的速度运行


有什么建议吗?

听起来操作系统需要一些时间才能意识到您的应用程序是一个巨大的资源消耗者。因此,几秒钟后,它会发现应用程序的文件有很多活动,只有在这之后,操作系统才会通过填充缓存和这样的操作来处理这些活动。

在“预热”过程中是否有大量磁盘活动,然后逐渐减少?我想知道您是否看到缓存被填充。在40-50k消息几乎全部静态数据加载后,您的应用程序是否进行了一些静态数据查找。如果是这种情况,您可以预加载这样的缓存。应用程序的增长时间可能在那里:堆增长、缓存增长,您还可以查看GC行为一次有多少线程处于活动状态?您是否有任何与线程生成等相关的费用。我不确定这是否相关,但这是我唯一的想法。在开始处理消息之前,是否可以尝试生成线程池。另外-如果限制线程数会发生什么情况????我想您可能会找到一种可能有用的模式。您使用的是什么版本的Java?HotSpot技术在VM中已经存在很长一段时间了,因此即使您的Java应用程序是“遗留”的,它也可能有一个称为HotSpot的动态优化器,它在收集了有关应用程序运行方式的足够信息后,将您的字节码编译为本机代码。当应用程序运行时,它会一直这样做。这对于任何Java服务器应用程序来说都是完全正常的行为——令人惊讶的是,所有的评论都没有提到这一点。