内存映射文件:优点和缺点?

时间:2011-12-15 21:00:26

标签: java ipc shared-memory memory-mapped-files

我需要在同一台机器上运行的两个Java应用程序(两个不同的JVM)之间共享数据。我确切地说要共享的数据很大(大约7 GB)。应用程序必须非常快速地访问数据,因为它们必须以非常高的速率应答传入的查询。我不希望应用程序为每个应用程序保存一份数据副本。

我已经看到一个选项是使用内存映射文件。应用程序A从某处获取数据(比如数据库)并将其存储在文件中。然后,应用程序B可以使用java.nio访问这些文件。我不确切知道内存映射文件是如何工作的,我只知道数据存储在一个文件中,并且该文件(或其中的一部分)被映射到内存区域(虚拟内存?)。因此,这两个应用程序可以读写内存中的数据,并且更改会自动(我猜?)提交到文件中。我也不知道文件的最大大小是否完全映射到内存中。

我的第一个问题是两个应用程序在这种情况下共享数据的不同可能性(我的意思是考虑到数据量非常大,并且访问这些数据必须非常快)?我确切地说这个问题与内存映射I / O无关,只是知道解决同样问题的其他方法是什么。

我的第二个问题是使用内存映射文件的优缺点是什么?

由于

2 个答案:

答案 0 :(得分:9)

  

我的第一个问题是两个应用程序共享数据的不同可能性是什么?

正如S.Lott指出的那样,机制中有批次

  

我的第二个问题是使用内存映射文件的优缺点是什么?

优点:

  • 非常快 - 根据您访问数据的方式,可能会使用zero-copy机制直接对数据进行操作而不会受到速度限制。必须注意以一致的方式更新对象
  • 应该非常便携 - 可以在Unix系统上使用大约25年(给予或接受),and apparently Windows has mechanisms too

缺点:

  • 单系统共享。如果要在多台计算机上分发应用程序,共享内存不是一个很好的选择。 Distributed shared memory systems are available,但他们觉得我的思维方式与错误的界面非常相似。
  • 即使在单个系统上,如果内存位于单个NUMA node上但需要由来自多个节点的处理器访问,则与为每个节点提供其自己的段相比,节点间请求可能会显着减慢处理速度记忆。
  • 您不能只存储指针 - 所有内容都必须存储为偏移到基地址,因为内存可能会映射到不同进程中的不同位置。我不知道这对Java对象意味着什么,尽管可能有人聪明地尽力让它对Java程序员透明。如果您没有使用他们提供的机制,那么您可能必须自己完成工作。 (在Java中没有实际的指针,也许这不是很麻烦。)
  • 事实证明,持续更新对象非常困难。在消息传递系统中传递immutable objects通常会导致程序具有较少的并发错误。 (Erlang中的并发编程感觉非常自然和直接。更多imperative languages中的并发编程往往会引入大量新的并发控制:semaphoresmutexes,{ {3}},spinlocks)。

答案 1 :(得分:1)

内存映射文件听起来很头疼。一个简单的选项,不易出错,可以使用具有群集感知缓存的共享数据库。这样只会写入数据库,并且可以从缓存中提供读取。

作为如何在休眠中执行此操作的示例,请参阅http://docs.jboss.org/hibernate/core/3.3/reference/en/html/performance.html#performance-cache