使用JNIEnv::FindClass:我需要释放返回的jclass引用
Using JNIEnv::FindClass: do I need to free the returned jclass reference?
假设我在实现native
函数存根的JNI函数中有以下代码:
JNIEnv* env; /*This is set to a valid JNIEnv* for this thread*/
jclass clz = env->FindClass("foo"); /*this has worked*/
我需要打电话吗
env->DeleteLocalRef(clz);
一旦我完成它?我不返回clz
回Java,所以我认为我需要删除本地引用?这看起来有点奇怪,因为像MethodID
一样,jclass
不包含对象实例。
调用DeleteLocalRef
永远不会出错,所以您应该始终调用它,否则您可能会遇到本地引用数量用尽的情况。
当你的JNI代码从Java调用时,它是短时间运行的,你可能足够幸运,本地引用在你返回Java调用者后为你清理,但是如果你从本机代码调用Java VM(所以没有"外部"Java VM框架,你的JNI代码被调用),那么你将很快用完你的本地变量,因为它们永远不会被一个不存在的Java调用者删除。
引用Java官方文档:
在大多数情况下,程序员应该依赖VM在本机方法返回后释放所有本地引用。但是,有时程序员应该显式释放局部引用。例如,考虑以下情况:
- 本地方法访问一个大的Java对象,从而创建一个对Java对象的本地引用。然后,本机方法在返回调用方之前执行额外的计算。对大Java对象的本地引用将防止该对象被垃圾收集,即使该对象在剩余的计算中不再使用。
- 本机方法创建了大量的本地引用,尽管不是所有的引用都同时使用。由于VM需要一定的空间来跟踪本地引用,因此创建太多的本地引用可能会导致系统耗尽内存。例如,本机方法循环遍历大型对象数组,检索元素作为局部引用,并在每次迭代时操作一个元素。在每次迭代之后,程序员不再需要对数组元素的局部引用。
不,你不需要调用DeleteLocalRef
。FindClass
返回一个本地引用。所以没有必要删除。JVM将在JNI调用完成后自动执行此操作。
但是如果你愿意,你可以删除本地引用。
相关文章:
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- 什么时候在C++中返回常量引用是个好主意
- 你能重载对象变量名本身返回的内容吗
- 为什么 Serial.println(<char[]>);返回随机字符?
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 如何获取std::result_of函数的返回类型
- QueryWorkingSet总是返回false
- (C++)分析树以计算返回错误值的简单算术表达式
- 访问者访问变体并返回不同类型时出错
- 如何返回一个类的两个对象相加的结果
- OpenInventor从9.8升级到10.4.2后,GLSL纹理返回零
- lower_bound()返回最后一个元素
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- 奇怪的(对我来说)返回声明 - 在谷歌上找不到任何关于它的信息
- 如何取消对nullptr的屏蔽,返回正确的对象
- 奇怪的结构&GCC&clang(void*返回类型)
- 架构决策:返回std::future还是提供回调
- 从python中调用C++函数并获取返回值
- 矩阵向量乘法(cublasDgemv)返回零
- 使用JNIEnv::FindClass:我需要释放返回的jclass引用