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

时间:2009-07-28 17:47:11

标签: java scala jvm

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

9 个答案:

答案 0 :(得分:12)

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

答案 1 :(得分:4)

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

更新以在评论中解决OP的问题:

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

public interface GraphAlgorithm {
  public void doStuff(Map<whatever> myBigGraph)
}

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

答案 2 :(得分:3)

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

答案 3 :(得分:0)

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

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

答案 4 :(得分:0)

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

然而,我对阅读你的帖子的初步想法是

  1. 这张图有多大?
  2. 是否可以优化您的装载程序?
  3. 我知道LinkedIn有vast graph of people and connections一直在内存中保存,需要几个小时才能重新加载。但我认为这是一个非常特殊的案例。

答案 5 :(得分:0)

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

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

答案 6 :(得分:0)

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

答案 7 :(得分:0)

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

答案 8 :(得分:0)

呜!迟到了。

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

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