繁体   English   中英

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

[英]How can I share memory between two JVM instances?

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

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

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

更新以解决OP的问题:

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

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

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

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

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

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

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

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

  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/ 它被很多大型项目所使用。 当然,您的对象必须是可序列化的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM