两个 JVM 之间的共享内存 [英] Shared Memory between two JVMs

查看:33
本文介绍了两个 JVM 之间的共享内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

JAVA 中有没有办法让两个 JVM(在同一台物理机器上运行)使用/共享相同的内存地址空间?假设 JVM1 中的生产者将消息放在特定的预定义内存位置,如果 JVM2 上的消费者知道要查看哪个内存位置,是否可以检索消息?

Is there a way in JAVA, for two JVMs (running on same physical machine), to use/share the same mermory address space? Suppose a producer in JVM1 puts messages at a particular pre-defined memory location, can the consumer on JVM2 retrive the msg if it knows which memory location to look at?

推荐答案

方案一:

我认为最好的解决方案是使用内存映射文件.这允许您在任意数量的进程之间共享内存区域,包括其他非 java 程序.您不能将 java 对象放入内存映射文件中,除非您将它们序列化.以下示例显示您可以在两个不同的进程之间进行通信,但您需要使其更加复杂以允许进程之间更好的通信.我建议您查看 Java 的 NIO 包,特别是类以及以下示例中使用的方法.

Solution 1:

The best solution in my opinion is to use memory mapped files. This allows you to share a region of memory between any number of process, including other non java programs. You can't place java objects into a memory mapped file, unless you serialize them. The following example shows that you can communicate between two different process, but you would need to make it much more sophisticated to allow better communication between the processes. I suggest you look at Java's NIO package, specifically the classes and methods used in the below examples.

服务器:

public class Server {

    public static void main( String[] args ) throws Throwable {
        File f = new File( FILE_NAME );

        FileChannel channel = FileChannel.open( f.toPath(), StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE );

        MappedByteBuffer b = channel.map( MapMode.READ_WRITE, 0, 4096 );
        CharBuffer charBuf = b.asCharBuffer();

        char[] string = "Hello client".toCharArray();
        charBuf.put( string );

        System.out.println( "Waiting for client." );
        while( charBuf.get( 0 ) != '' );
        System.out.println( "Finished waiting." );
    }
}

客户:

public class Client {

    public static void main( String[] args ) throws Throwable {
        File f = new File( FILE_NAME );
        FileChannel channel = FileChannel.open( f.toPath(), StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE );

        MappedByteBuffer b = channel.map( MapMode.READ_WRITE, 0, 4096 );
        CharBuffer charBuf = b.asCharBuffer();

        // Prints 'Hello server'
        char c;
        while( ( c = charBuf.get() ) != 0 ) {
            System.out.print( c );
        }
        System.out.println();

        charBuf.put( 0, '' );
    }

}

<小时>

解决方案 2:

另一种解决方案是使用 Java Sockets 来回通信和进程之间.这有一个额外的好处,即允许非常轻松地通过网络进行通信.可以说这比使用内存映射文件慢,但我没有任何基准来支持该声明.我不会发布实现这个解决方案的代码,因为实现一个可靠的网络协议会变得非常复杂并且是特定于应用程序的.可以通过快速搜索找到许多不错的社交网站.


Solution 2:

Another solution is to use Java Sockets to communicate back and forth between processes. This has the added benefit of allowing communication over a network very easily. It could be argued that this is slower than using memory mapped files, but I do not have any benchmarks to back that statement up. I won't post code to implementing this solution, as it can become very complicated to implement a reliable network protocol and is fairly application specific. There are many good networking sites that can be found with quick searches.

现在上面的例子是如果你想在两个不同的进程之间共享内存.如果您只想读取/写入当前进程中的任意内存,您应该首先了解一些警告.这违背了 JVM 的整个原则,你真的不应该在生产代码中这样做.如果您不非常小心,您就违反了所有安全性,并且很容易使 JVM 崩溃.

Now the above examples are if you want to share memory between two different process. If you just want to read/write to arbitrary memory in the current process, there are some warnings you should know first. This goes against the entire principle of the JVM and you really really should not do this in production code. You violate all safety and can very easily crash the JVM if you are not very careful.

话虽如此,实验还是很有趣的.要读取/写入当前进程中的任意内存,您可以使用 sun.misc.Unsafe 类.这在我知道并使用过的所有 JVM 上都提供.此处.

That being said, it is quite fun to experiment with. To read/write to arbitrary memory in the current process you can use the sun.misc.Unsafe class. This is provided on all JVMs that I am aware of and have used. An example on how to use the class can be found here.

这篇关于两个 JVM 之间的共享内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆