【问题标题】:JNI objects creation and memory managementJNI 对象创建和内存管理
【发布时间】:2012-02-20 23:19:21
【问题描述】:

我有以下 JNI 方法,它在本地创建 Java 对象的集合,然后将它们返回给 Java:

JNIEXPORT jobject JNICALL Java_com_test_myClass_myMethod(JNIEnv * env, jclass klass) {
    jclass arrayClass = env->FindClass("java/util/ArrayList");
    jmethodID initMethod = env->GetMethodID(arrayClass, "<init>", "()V");
    jmethodID addMethod = env->GetMethodID(arrayClass, "add", "(Ljava/lang/Object;)Z");
    jobject myArray = env->NewObject(arrayClass, initMethod);

    env->CallBooleanMethod(myArray, addMethod, env->NewStringUTF("Hello"));
    env->CallBooleanMethod(myArray, addMethod, env->NewStringUTF("World"));

    return myArray;
}

我需要释放在本机代码中创建的对象,还是由 GC 自动完成? 如果我这样做,我该怎么做,因为我需要将它返回给 Java?

【问题讨论】:

  • 我认为这将取决于本机代码来进行自己的内存管理。在这种情况下,我想您需要添加另一个本机方法来释放分配的对象,当您完成它们时手动调用它们。更一般地说,如果您正在使用 JNI 做事,那么我希望您已经为一个充满伤害的世界做好了准备。这个答案可能会有所帮助:stackoverflow.com/questions/214699/…
  • @aroth - 错误。如果你在 JNI 中分配 Java 对象,它们是 Java 对象,归 GC 所有。
  • @bmargulies - 有道理,但是对于分配非 Java 对象/内存的本机代码,例如通过调用 malloc() 呢?
  • @aroth 不是这个问题的意思。

标签: java c++ memory-management memory-leaks java-native-interface


【解决方案1】:

您不需要释放在本机代码中创建的 Java 对象。事实上,你不能。当没有更多引用时,垃圾收集器可能会释放该对象。

有时在本地代码中释放对 Java 对象的引用 很有用。当本机代码持有但不再需要对大对象或大量引用的引用时,这可以减少内存需求。

来自:JNI specification 中的“全局和本地引用”。

在大多数情况下,程序员应该依靠 VM 在本地方法返回后释放所有本地引用。但是,有时程序员应该显式地释放本地引用。例如,考虑以下情况:

  • 本机方法访问大型 Java 对象,从而创建对 Java 对象的本地引用。然后,本机方法在返回给调用者之前执行额外的计算。对大型 Java 对象的本地引用将防止该对象被垃圾回收,即使该对象不再用于剩余的计算。
  • 本机方法会创建大量本地引用,尽管并非所有这些都同时使用。由于 VM 需要一定的空间来跟踪本地引用,因此创建过多的本地引用可能会导致系统内存不足。例如,本机方法循环遍历大量对象,检索元素作为本地引用,并在每次迭代时对一个元素进行操作。每次迭代后,程序员不再需要对数组元素的本地引用。

提供了更多细节 请参阅 JNI 程序员指南中的 "Freeing References"

【讨论】:

  • 我阅读了关于释放引用的指南,但有一个问题:在我的初始帖子中多次调用该方法会造成资源耗尽问题吗?如果是,我在哪里可以释放参考资料,因为我还需要归还它们?
  • 每次调用后都会自动释放本地引用。您不必显式执行此操作,除非 1)您已创建全局引用,或 2)出于链接中描述的原因,需要在调用完成之前释放本地引用。您返回的引用正在被复制。 myArray 和返回的引用都指向同一个 Java 对象。
  • 谷歌图书链接现在也失效了。 Sun 文档可以在 Internet 档案中找到:web.archive.org/web/20070812015712/http://java.sun.com/docs/…(第 5.2 节是“释放参考”一节)。
  • 将链接从 1999 年的“程序员指南和规范”更改为当前的在线“Java 本机接口规范”。并为新链接何时化为灰烬添加了块引用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
  • 2012-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多