我有一个Java应用程序,它使用几个MulticastSocket实例来侦听几个UDP多播源。 每个这样的sockets由专用线程处理。
线程读取每个Datagram,parsing它的内容,并写入log(log4j)数据包的序列ID(long)和接收数据报的时间戳。
当我尝试在Windows Server 2008 R2上运行2个具有2 * 6内核的相同应用程序的实例并比较2个应用程序创build的2个日志时,我注意到相当频繁的数据包计时是不一样的。
大多数数据包同时被2个应用程序接收(milis),但是两个应用程序在同一个数据包的接收时间之间经常会有大约1-7ms的差异。
我尝试在NIC中分配更多的缓冲区,并且使得套接字读取缓冲区更大。 另外,我尝试最小化GC运行,并且还使用了-verbose:gc,并且可以看到GC时间和有问题的时序差异不会同时发生。 这使我可以假设我的问题不是GC相关的。
未观察到丢包问题,并且带宽问题不太可能。
想法/意见是受欢迎的。 谢谢。
默认情况下,Windows定时器中断频率为100 Hz(每10ms 1个滴答)。 这意味着操作系统不能保证Java线程以更高的精度被唤醒。
下面是一篇着名的James Holmes关于Java时间的文章摘录 – 可能是你的情况:
对于Windows用户,特别是在双核或多处理器系统上(如果您在系统上看到Java或其他应用程序(游戏,多媒体演示)中的时序行为不稳定)然后尝试在boot.ini文件中添加/ usepmtimer开关。
PS:绝不是我在Windows性能优化领域的可信度,也是从Windows 2008开始支持HPET,但是它与定时器中断频率有何关系对我来说是个谜。
对于一个6核心的机器来说,7ms是一个非常好的结果,而java中的漂移将远高于垃圾回收器的使用。不要忘记,java运行时也有它自己的开销。