scala 如何在两个 JVM 实例之间共享内存?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1195633/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I share memory between two JVM instances?
提问by Alexy
I build a huge graph in JVM (Scala) which I want to use repeatedly, tweaking algorithms. I'd rather not reload it each time from disk. Is there a way to have it sit in one JVM while connecting from another, where the algorithms are being developed?
我在 JVM (Scala) 中构建了一个巨大的图形,我想重复使用它,调整算法。我不想每次都从磁盘重新加载它。有没有办法让它位于一个 JVM 中,同时从另一个 JVM 连接,在那里开发算法?
采纳答案by bdonlan
Save your graph to disk, then map it into memory with MappedByteBuffer. Both processes should use the same memory, which will be shared with the page cache.
将图形保存到磁盘,然后使用MappedByteBuffer将其映射到内存中。两个进程应该使用相同的内存,这将与页面缓存共享。
回答by Peter Recore
Two JVMs sounds more complicated than it needs to be. Have you considered doing a kind of "hot deploy" setup, where your main program loads up the graph, displays the UI, and then asks for (or automatically looks for) a jar/class file to load that contains your actual algorithm code? That way your algorithm code would be running in the same jvm as your graph, but you wouldn't have to reload the graph just to reload a new algorithm implementation.
两个 JVM 听起来比实际需要的更复杂。您是否考虑过进行一种“热部署”设置,即您的主程序加载图形、显示 UI,然后请求(或自动查找)一个 jar/class 文件以加载包含您的实际算法代码的文件?这样,您的算法代码将在与图形相同的 jvm 中运行,但您不必为了重新加载新算法实现而重新加载图形。
UPDATE to address OP's question in comment:
更新以在评论中解决 OP 的问题:
Here's how you could structure your code so that your algorithms would be swappable. It doesn't matter what the various algorithms do, so long as they are operating on the same input data. Just define an interface like the following, and have your graph algorithms implement it.
以下是您如何构建代码以便您的算法可交换。各种算法做什么并不重要,只要它们对相同的输入数据进行操作即可。只需定义一个如下所示的接口,并让您的图形算法实现它。
public interface GraphAlgorithm {
public void doStuff(Map<whatever> myBigGraph)
}
If your algorithms are displaying results to some kind of widget, you could pass that in as well, or have doStuff() return some kind of results object.
如果您的算法向某种小部件显示结果,您也可以将其传入,或者让 doStuff() 返回某种结果对象。
回答by Alexander Azarov
Did you consider OSGi platform? It lives in a single JVM, but will allow you to upgrade bundles with algorithms without platform restart. Thus you may have a long-term running bundle with your huge data structures and short-term algorithm bundles taking access to the data.
你考虑过 OSGi 平台吗?它存在于单个 JVM 中,但允许您在不重启平台的情况下使用算法升级包。因此,您可能有一个长期运行的包,其中包含庞大的数据结构和访问数据的短期算法包。
回答by firstthumb
Terracottashares memory between many JVM instances so you can easily apply cluster to your system.
Terracotta在许多 JVM 实例之间共享内存,因此您可以轻松地将集群应用于您的系统。
回答by critium
Woo! late to the party.
哇!聚会迟到了。
If its on a local machine, similar to mapped byte buffers, there is apache direct memory. http://directmemory.apache.org/
如果它在本地机器上,类似于映射字节缓冲区,则有 apache 直接内存。 http://directmemory.apache.org/
If you want it distributed, give http://hazelcast.org/a try. Its used by a lot of large projects. Of course, your objects must be serializable.
如果您想分发它,请尝试http://hazelcast.org/。它被许多大型项目使用。当然,您的对象必须是可序列化的。
回答by critium
if the problem is just to dynamicly load and run your code without name clashes a custom class loader could be enough. for a new run just cache all class files in a new classloader.
如果问题只是动态加载和运行您的代码而不会发生名称冲突,那么自定义类加载器就足够了。对于新的运行,只需将所有类文件缓存在新的类加载器中。
回答by Nick Lewis
Have you considered simply using a smaller amount of sample data for testing your algorithms?
您是否考虑过简单地使用较少的样本数据来测试您的算法?
回答by Dani Cricco
If is expensive to build your graph maybe you can serialize the object.
如果构建图形的成本很高,也许您可以序列化对象。
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
Then you can build your object from the file
然后你可以从文件中构建你的对象
ByteArrayInputStream inputBuffer = new ByteArrayInputStream(b);
ObjectInputStream inputStream = new ObjectInputStream(inputBuffer);
try {
Graph graph = (Graph) inputStream.readObject();
} finally {
if (inputStream != null) {
inputStream.close();
}
}
Just replace the ByteArrayInputStream with a FileInputStream
只需用 FileInputStream 替换 ByteArrayInputStream
回答by OscarRyz
Using RMI perhaps? Have one instance working as server and the rest as clients?
也许使用RMI?有一个实例作为服务器工作,其余的作为客户端?
I think it would be much more complicated than reloading from disk.
我认为这比从磁盘重新加载要复杂得多。
回答by Brian Agnew
You can certainly create an interface onto it and expose it via (say) RMI.
您当然可以在其上创建一个接口并通过(例如)RMI公开它。
My initial thoughts on reading your post, however, are
然而,我在阅读您的帖子时最初的想法是
- just how big is this graph ?
- is it possible to optimise your loading procedure instead ?
- 这个图有多大?
- 是否可以优化您的加载程序?
I know LinkedIn have a vast graph of people and connectionsthat is held in memory all the time and that takes several hours to reload. But I figure that's a truly exceptional case.
我知道 LinkedIn 有一个庞大的人和关系图,这些图一直保存在内存中,需要几个小时才能重新加载。但我认为这是一个真正的例外情况。

