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

Mic*_*che 6 java ipc shared-memory memory-mapped-files

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

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

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

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

谢谢

sar*_*old 10

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

正如S.Lott指出的那样,有很多机制:

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

优点:

  • 非常快 - 根据您访问数据的方式,可能会使用零拷贝机制直接对数据进行操作而不会受到速度损失.必须小心以一致的方式更新对象.
  • 应该是非常便携的 - 可以在Unix系统上使用大约25年(赠送或接受),显然Windows也有机制.

缺点:

  • 单系统共享.如果要在多台计算机上分发应用程序,共享内存不是一个很好的选择.分布式共享内存系统是可用的,但他们感觉非常像我的思维方式的错误接口.
  • 即使在单个系统上,如果存储器位于单个NUMA节点上但需要由来自多个节点的处理器访问,则与给予每个节点其自己的存储器段相比,节点间请求可能显着减慢处理.
  • 您不能只存储指针 - 所有内容都必须存储为基址的偏移量,因为内存可能会映射到不同进程中的不同位置.我不知道这对Java对象意味着什么,尽管可能有人聪明地尽力让它对Java程序员透明.如果您没有使用他们提供的机制,那么您可能必须自己完成工作.(如果没有Java中的实际指针,也许这不是很麻烦.)
  • 事实证明,持续更新对象非常困难.在消息传递系统中传递不可变对象通常会导致程序具有较少的并发错误.(Erlang中的并发编程感觉非常自然和直接.更多命令式语言中的并发编程往往会引入大量新的并发控件:信号量,互斥锁,自旋锁,监视器).