同一台机器上JVM之间最快的通信方式

5
我需要从在同一台机器上运行的另一个JVM中调用一个方法。这个方法需要使用Java/本地代码的性能被多次调用。它是一个小输入小输出的方法。其他JVM也运行在同一台机器上。
如何最快地调用此方法并从“附近”运行的其他JVM中检索结果?
可能的选择有RMI、管道、套接字、JMS、经过优化的同一机器间的JVM之间通信支持和JVM中的某些低级黑客。欢迎任何想法,无论多么专业化。

2
JMX 高效且易于实现。 - Assen Kolov
1
@Nambari 一个重复的问题,但我不同意那个答案。;) - Peter Lawrey
1
@AssenKolov JMX很容易实现没错,但即使是它最好的朋友也不会称其为高效。作为RMI上的反射层,高效吗? - user207421
谢天谢地,StackOverflow上并不是每个人都是强迫症式的关闭者。我实际上得到了非常好的答案。 - Nick
@EJP 确实,你是对的。我想我原本的意思是“开发工作量较小”,这只是容易,而不是高效。 - Assen Kolov
2个回答

5
在同一台机器上的JVM之间进行通信的最快方式是使用共享内存,例如通过内存映射文件。这比通过回环套接字使用的速度快了100倍,例如200ns的往返时间与套接字的10-20微秒的往返时间相比。
其中一种实现是Java Chronicle,顺便提一下,100ns的延迟包括消息的持久性。
是否需要这些解决方案并不是您应该想当然的事情。通常,当人们说他们必须拥有“最快”的时候,他们真正意思是他们不知道它需要多快,因此如果他们选择最快的解决方案,它应该是正确的解决方案。这通常是不正确的,因为采用最快的解决方案通常意味着在设计和实现中做出妥协,而如果只知道要求是什么,可能根本不需要这些妥协。
简而言之,除非您具有特定的可测量的延迟和/或吞吐量要求,否则应该假定最简单的解决方案才是您真正想要的。如果在更好地了解所需内容后发现它不适合,则可以将其替换为更快的东西。

谢谢!比套接字快100倍已经足够快了。现在要检查实现的复杂性。我知道Java 1.4中有一些内存映射支持。JNI不是一个选择。 - Nick
你仍然需要首先明确你的需求,但既然你似乎不想这样做 ;) 我已经添加了一个这样的库的链接。 - Peter Lawrey
在我决定下一步该做什么之前,我需要自己分析内存映射的 JVM 间通信。我的要求非常明确,但我选择不公开分享,因为它们是无关紧要和潜在敏感的。最快才是最快的。如果内存映射是最快的方法,但仍然不符合要求,则使用 JVM 间通信,或者追求其他选项。我会检查你的库,如果它不使用 JNI,我会使用它。非常感谢! - Nick
它有使用JNI或JNA进行线程亲和力以最小化抖动的选项,但那是在不同的库中且不是必需的。我经常遇到一些具有“巨大”要求的项目,但当真正需要时,几乎任何合适的解决方案都可以胜任。 - Peter Lawrey
我很好奇为什么不需要JNI,但是需要最快的速度。你为什么排除了JNI呢? - Peter Lawrey
1
当然,JNI 可能会导致 JVM 崩溃。在我的设置中,除了 JIT 编译器错误之外的崩溃是不可容忍的。 - Nick

1

另一个可能性是0MQ (ZeroMQ),不过这取决于你对“最快”的定义 - zeromq在吞吐量方面表现出色,但如果你绝对需要最低的延迟,它可能不是最优选择。

对于只有两个JVM来说,ZeroMQ可能有些大材小用,但它的优点是,如果你以后想将其中一个JVM移动到另一台机器上,或者与非Java进程通信,ZeroMQ仍然可以正常工作 - 它还可以扩展到更大规模、更复杂的通信。


所以我们在谈论大量的输入/输出?这也可能很有用。谢谢! - Nick
ZeroMQ 的往返延迟约为 30 微秒。 如果这种延迟可以接受,它可能比其他选择更好。 - Peter Lawrey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接