Java中共享内存的任何概念

时间:2009-09-29 09:34:39

标签: java memory shared

AFAIK,Java中的内存基于堆,内存从中动态分配给对象,并且没有共享内存的概念。

如果没有共享内存的概念,那么Java程序之间的通信应该是耗时的。在C中,与其他通信模式相比,通过共享内存可以更快地进行进程间通信。

如果我错了,请纠正我。另外,两个Java程序相互交流的最快方式是什么。

10 个答案:

答案 0 :(得分:23)

至少有两种方法 - RAM DriveApache APR

详情herehere以及一些效果衡量标准。

答案 1 :(得分:14)

由于没有正式的API来创建共享内存段,因此需要使用帮助库/ DDL和JNI来使用共享内存来让两个Java进程相互通信。

实际上,由于Java支持线程,因此这很少成为问题,因此您可以在同一个Java VM中运行两个“程序”。那些将共享相同的堆,因此通信将是即时的。此外,由于共享内存段出现问题,您无法获得错误。

答案 2 :(得分:9)

Peter Lawrey的Java Chronicle项目值得一看。

这些是我前一段时间比较各种堆外和堆上选项的some tests

答案 3 :(得分:8)

要注意的一件事是使用memory-mapped files,使用Java NIO's FileChannel类或类似的(请参阅map()方法)。我们已经非常成功地使用它来在同一台机器上的Java进程和C本机进程之间进行通信(在我们的例子中是单向的)。

我承认我不是文件系统专家(幸运的是我们确实有一个人员!)但我们的表现绝对超快 - 实际上你将页面缓存的一部分视为文件和阅读+直接写入它而不需要系统调用的开销。我不确定保证和一致性 - 在Java中有一些方法可以强制将更改写入文件,这意味着它们(通常?通常?通常?不确定)写入实际的基础文件(有点?非常?非常?)懒洋洋地说,这意味着在某些时候它基本上只是一个共享的内存段。

理论上,据我所知,内存映射文件实际上可以由共享内存段支持(我认为它们只是文件句柄)但是我不知道在没有Java的情况下这样做的方法JNI。

答案 4 :(得分:7)

共享内存有时很快。有时它不会 - 它会伤害CPU缓存和同步通常是一种痛苦(并且它应该依赖于互斥体等等,可能会造成严重的性能损失)。

Barrelfish是一个操作系统,它表明使用消息传递的IPC实际上比共享内存更快,因为内核数量增加(在传统的X86架构上以及你猜的更奇特的NUMA NUCA东西)正在瞄准)。

因此,您对共享内存快速的假设需要针对您的特定方案和目标硬件进行测试。这些天它不是一般的声音假设!

答案 5 :(得分:4)

我可以想到几种类似的技术:

  1. 几年前,有一项名为JavaSpaces的技术,但如果你问我的话,这种技术似乎永远不会成功。
  2. 现在有分布式缓存技术,例如CoherenceTangosol
  3. 不幸的是,它们没有合适的共享内存速度,但它们确实处理并发访问等问题。

答案 6 :(得分:2)

最简单的方法是让两个进程实例化同一个内存映射文件。实际上,它们将共享相同的堆外内存空间。您可以获取此内存的物理地址,并使用<script type="text/javascript"> var maps = []; function InitMap(latitude,longitude,container) { var myOptions = { zoom: 14, center: new google.maps.LatLng(latitude, longitude), mapTypeId: google.maps.MapTypeId.ROADMAP } maps.push( new google.maps.Map( document.getElementById(container), myOptions) ); } </script> <c:forEach var="location" items="${locations}"> <div id="item"> <h1>${location.name}</h1> <div id="${location.mapName}"></div> <script type="text/javascript"> InitMap(${location.lat}, ${location.long}, '${location.mapName}'); </script> </div> </c:forEach> 来写入/读取基元。它通过putXXXVolatile / getXXXVolatile方法支持并发。看看CoralQueue,它可以在同一个JVM中轻松提供IPC以及线程间通信。

免责声明:我是CoralQueue的开发者之一。

答案 7 :(得分:1)

与Peter Lawrey的Java Chronicle类似,您可以尝试Jocket

它也使用MappedByteBuffer但不保留任何数据,并且可以用作Socket / ServerSocket的替代品。

1kB乒乓球的往返延迟大约是半微秒。

答案 8 :(得分:1)

MappedBus(http://github.com/caplogic/mappedbus)是我在github上添加的库,它通过消息传递在多个(两个以上)Java进程/ JVM之间启用IPC。

传输可以是内存映射文件或共享内存。要将它与共享内存一起使用,只需按照github页面上的示例进行操作,但将读者/编写者指向“/ dev / shm /".

下的文件。

它是开源的,并且在github页面上完整地解释了实现。

答案 9 :(得分:0)

Cowan提供的信息是正确的。但是,即使共享内存在多​​个线程(和/或进程)中同时也不会总是相同。关键的根本原因是Java内存模型(它建立在硬件内存模型上)。请参阅Can multiple threads see writes on a direct mapped ByteBuffer in Java?,了解有关该主题的非常有用的讨论。