【问题标题】:Java JNI - associating resources allocated in C with java objects?Java JNI - 将 C 中分配的资源与 java 对象相关联?
【发布时间】:2010-01-04 07:54:04
【问题描述】:

我想在 C 中分配一些内存并将其与 java 对象实例关联,如下所示:

void configure(JNIEnv *object, jobject obj, ....) {
  char *buf = new char[1024];
  // associated <buf> with <obj> somehow
}

然后当 java 对象被垃圾回收时释放内存 - 我可以通过调用 java 对象的 finalize() 方法中的 JNI 函数来做到这一点。

问题是,如何将 C 指针与 java 对象关联?在对象中保留一个 long 字段并将指针转换为 long?有没有更好的办法?

【问题讨论】:

  • 有点,在那个问题中没有讨论如何将 C 对象关联到 java 实例。在给出的示例中,指针被强制转换为 long。这是唯一的方法吗?

标签: java c++ c java-native-interface android-ndk


【解决方案1】:

一般来说,如果要将指针从 C 传输到 Java,建议使用long,以便在平台为 64 位的情况下有足够的位来保存指针值。

然后,看看ByteBuffer.allocateDirect(),它创建了一个ByteBuffer 实例,该实例可以与C 共享内存。您可以从Java 端分配这样一个直接ByteBuffer,然后将它作为jobject 传递给一个JNI 函数,在这个 JNI 函数中使用GetDirectBufferAddress 函数。

另一种方法是使用来自本机端的NewDirectByteBuffer JNI 函数包装一个本机内存区域。它给你一个jobject 你传回Java 端(注意本地和全局引用)。请注意,一旦创建了包装本机内存的直接ByteBuffer,您仍然负责管理本机内存:在某些时候,您将不得不在您的本机代码中调用delete buf;,Java 赢了不要为你做。

【讨论】:

  • 谢谢!如果我理解正确,使用 ByteBuffer.allocateDirect() 回避指针传递+内存管理;这样 ByteBuffer 管理内存。
  • 从Java端分配直接ByteBuffer让Java分配内存块,当finalize运行时将被释放。唯一的缺点是你不知道垃圾收集器什么时候通过,所以你真的不知道内存什么时候被释放,它会在你用完缓冲区后被释放。
  • der 是加载库的方式...是 der 卸载的任何方式..?
【解决方案2】:

Java 没有任何本地指针的概念,因此将其存储为 long 是唯一真正的选择。但是你不应该依赖finalize 来释放指针; finalize 方法作为清理资源的手段是不可靠的。详情请见this question

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-27
    • 2015-05-16
    • 1970-01-01
    • 2012-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多