当前位置: 首页 > 面试题库 >

JNI对象创建和内存管理

裴心水
2023-03-14
问题内容

我有以下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?


问题答案:

您不需要释放在本机代码中创建的Java对象。实际上,您不能。当没有其他引用时,垃圾收集器可以释放对象。

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

来自:JNI规范中的“全局和本地引用”

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

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


提供了更多详细信息,请参见《
JNI程序员指南》中的“释放参考”。



 类似资料:
  • OpenStack对象存储是一个分布式的对象存储平台,支持API调用。该功能可以直接结合进其他应用中,也可以用来存储各种文件,包括虚拟机镜像、备份、归档、甚至是媒体文件。在OpenStack控制台,用户暂时只能管理容器和镜像。 在OpenStack对象存储中,容器是存放对象文件的空间,就像Windows或者Linux的文件夹是存放文件的空间一样。只是容器和容器不能像文件夹一样嵌套。OpenStac

  • 问题内容: 我有两个问题: 如果我有对方法的JNI调用而JNI方法泄漏内存该怎么办。此方法完成后,JVM垃圾收集器将能够取回该内存。我听说JVM不管理JNI使用的堆空间吗?但是JNI使用的内存是Java进程使用的内存的一部分吗? 使用JNI来实现IPC是否绝对必要?还有哪些其他流行的Java技术?或者是否有一个开放源代码库来实现Java共享内存? 问题答案: 否:“ JNI框架不为在本机端执行的代

  • 问题内容: 我需要使用NDK以及JNI将一些功能实现到Android应用程序中。 这是我所写的C代码: 我的问题或多或少在代码内得到了解释。也许还可以:函数(jobject)的返回类型可以吗? 现在,NDKTest.java: 当我尝试运行代码时,它不起作用。 问题答案: 既然是内部类,那么获得它的方法就是 内部类的约定在权威规范中并未真正明确记录,但是根深蒂固地存在于如此多的工作代码中,因此不太

  • 我是JNI(和java)的新手,所以如果这只是一个愚蠢的错误,我提前道歉。但是,经过大量的搜索,我找不到一个解释或解决办法。 我有一个名为

  • 问题内容: 我有一个JNI回调: 当我像这样(空有用的代码)运行它时,会发生内存泄漏。如果我注释掉整个方法,则不会泄漏。连接/分离线程的正确方法是什么? 我的应用程序处理实时声音数据,因此负责数据处理的线程必须尽快完成,以便为下一批做好准备。因此,对于这些回调,我创建了新线程。每秒有数十个甚至数百个它们,它们将自己附加到JVM,调用一个回调函数来重绘图形,分离并消亡。这是做这些事情的正确方法吗?如

  • 一、对象的创建 1.虚拟机遇到一个new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用; 2.检查这个符号引用代表的类是否已经被加载,解析和初始化过。如果没有,那必须先执行响应的类加载过程; 3.在类加载检查功通过后,为新生对象分配内存。对象所需的内存大小在类加载完成后便可完全确定。 二、对象的内存布局 分为3个区域:对象头,实例数据,对齐填充。 对象头: 包括两部分信息