【问题标题】:Java unmanaged memory streamJava 非托管内存流
【发布时间】:2012-01-04 15:58:16
【问题描述】:

我正在尝试设计一个 API,以允许我的 Java 应用程序连接到专有的进程间消息传递环境。消息预先存在于非托管内存中。一旦我收到一条消息,我希望有一个流来读取和写入消息。虽然我了解 JNI 的基础知识,但我很难理解哪些标准 Java 类可以帮助创建到非托管内存的流。

如有任何指点,我将不胜感激

问候

【问题讨论】:

  • 指针......你明白了吗......

标签: java java-native-interface


【解决方案1】:

我会使用直接的 ByteBuffer。您可以通过 JNI 更改地址和限制。一旦这样做了,您就可以读取或更改此 ByteBuffer 中的任何内容,并且它将根据“非托管”大小进行更改。

ByteBuffer 支持小端和大端以及所有原始类型的读写。


这样做的一种原始方法是使用 Unsafe 类。它支持在内存的随机区域访问原语(就像指针一样)它还在许多情况下简化为单个机器代码指令。 Unsafe 既不安全也不可移植,如果您可以使用 ByteBuffer,它是一个更好的选择。

【讨论】:

  • 这听起来很积极,你有使用它的例子吗?我可以参考一下?
  • 没有,但我以前就是这样用过的。您覆盖的地址确实会导致内存泄漏,因为 ByteBuffer 有一个 Cleaner 对象,该对象具有由 ByteBuffer GCed 释放的原始地址。
  • 您是否建议在 Java 中创建一个 ByteBuffer,然后在 C 中更改地址?你遇到过NewDirectByteBufferJNI 电话吗?
  • 您可以这样做,前提是您可以轻松地重用 ByteBuffer。在 Java 中创建它使得重用(从而避免产生垃圾)非常简单。
【解决方案2】:

JNI API 有一个名为NewDirectByteBuffer 的方法,声明为:

jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity);

它所做的是获取一个内存区域,由指向它顶部的void* 和一个长度来描述,并创建一个包裹它的ByteBuffer。这不是副本;对缓冲区的更改将更改内存区域中的数据。

ByteBuffer 有一个非常丰富的 API。没有标准的方法来创建读取的 InputStream 或写入的 OutputStream,但是这样的东西很容易编写。

【讨论】:

    猜你喜欢
    • 2010-11-24
    • 2012-01-30
    • 1970-01-01
    • 2020-07-11
    • 1970-01-01
    • 2013-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多