如何在两个JVM实例之间共享内存?

我在JVM(Scala)中构建了一个巨大的图形,我想重复使用它,调整算法。 我不想每次都从磁盘重装它。 有没有办法让它在一个JVM中连接而从另一个JVM连接,算法正在开发中?

将图形保存到磁盘,然后使用MappedByteBuffer将其映射到内存中。 两个进程都应使用相同的内存,这些内存将与页面缓存共享。

两个JVM听起来比它需要的更复杂。 您是否考虑过进行一种“热部署”设置,主程序加载图形,显示UI,然后请求(或自动查找)要加载的jar / class文件,其中包含您的实际算法代码? 这样,您的算法代码将在与图形相同的jvm中运行,但您不必重新加载图形只是为了重新加载新的算法实现。

更新以解决OP的问题:

以下是如何构建代码以使您的算法可以交换的方法。 各种算法的作用并不重要,只要它们在相同的输入数据上运行即可。 只需定义如下所示的界面,并让您的图算法实现它。

public interface GraphAlgorithm { public void doStuff(Map myBigGraph) } 

如果您的算法将结果显示给某种窗口小部件,您也可以将其传递给,或者让doStuff()返回某种结果对象。

您是否考虑过OSGi平台? 它位于单个JVM中,但允许您在没有平台重启的情况下使用算法升级捆绑包。 因此,您可能拥有一个长期运行的捆绑包,其中包含大量数据结构和短期算法捆绑包,可以访问数据。

也许使用RMI? 有一个实例作为服务器,其余实例作为客户端吗?

我认为这比从磁盘重新加载要复杂得多。

您当然可以在其上创建一个接口并通过(例如) RMI公开它。

但是,我对阅读你的post的初步想法是

  1. 这个图有多大?
  2. 是否可以优化您的装载程序?

我知道LinkedIn有一个庞大的人员和连接图表,这些图表一直存在于内存中,需要几个小时才能重新加载。 但我认为这是一个非常特殊的案例。

如果问题只是在没有名称冲突的情况下动态加载和运行代码,那么自定义类加载器就足够了。 对于新的运行,只需将所有类文件缓存到新的类加载器中。

您是否考虑过使用少量样本数据来测试算法?

如果构建图形的成本很高,也许可以序列化对象。

 ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(bos); out.writeObject(graph); out.flush(); byte b[] = bos.toByteArray(); //you can use FileOutputStream instead of a ByteArrayOutputStream 

然后,您可以从文件中构建对象

 ByteArrayInputStream inputBuffer = new ByteArrayInputStream(b); ObjectInputStream inputStream = new ObjectInputStream(inputBuffer); try { Graph graph = (Graph) inputStream.readObject(); } finally { if (inputStream != null) { inputStream.close(); } } 

只需用FileInputStream替换ByteArrayInputStream即可

Terracotta在许多JVM实例之间共享内存,因此您可以轻松地将群集应用于您的系统。

呜! 迟到了。

如果它在本地机器上,类似于映射的字节缓冲区,则有apache直接内存。 http://directmemory.apache.org/

如果您想分发它, 请尝试http://hazelcast.org/ 。 它被很多大型项目所使用。 当然,您的对象必须是可序列化的。