JNI local reference table overflow

48 篇文章 2 订阅
3 篇文章 0 订阅
Context

JNI创建的reference太多,导致崩溃。具体查找 jString, jclass, jobject

简要分析

什么是Local reference

Every argument passed to a native method, and almost every object returned by a JNI function is a “local reference”.

This applies to all sub-classes of jobject, including jclass, jstring, and jarray (类型)

  1. native 方法的参数
JNIEXPORT jlong JNICALL Java_com_TestClass_testMethod(JNIEnv *env, jobject obj, jstring path1, jstring path2, jstring path3, jstring path4)

方法参数列表中的 jstring jobject

  1. JNI方法的返回值(绝大部分)
	const char *str_path1 = env->GetStringUTFChars(path1, 0);
	env->ReleaseStringUTFChars(path1, str_path1);
什么是JNI方法

JNIEnv指向的方法,也就是 env->方法,当然C和C++调用方式不同

什么是JNIEnv

指向JNI函数表的接口指针(也就是指向 JNI方法表的指针,所以env->function, function是JNI函数就很明白了)

还有什么reference

还有NewGlobalRef、NewWeakGlobalRef

与localReference区别

localReference只作用于当前的方法:
jobject obj对应的java对象 TestClass testObj, 即使 testObj 在native方法调用后仍旧存在,在native方法后调用 obj也是失败的。

jclass localClass = env->FindClass("MyClass");
jclass globalClass = reinterpret_cast<jclass>(env->NewGlobalRef(localClass));
NewGlobalRef

显然就是全局的引用,允许testObj的作用于超出方法。也是GC root的知识点(垃圾回收)。

NewWeakGlobalRef

相当于java的weak reference,不妨碍 java gc testObj。所以NewWeakGlobalRef引用的java对象有可能为null,所以需要判断
(*env)->IsSameObject(env, obj, null)

reference不同通过==来判断,引用的是否为相同的java对象,需要上述IsSameObject判断

LocalReference多少是多

java文档保证最低16个,我的bug是Android7.1.1手机,日志显示localReference最多512个。是for循环里创建string忘了回收

解决
		env->SetObjectArrayElement(results,i,env->NewStringUTF(json_results[i].c_str()));

改为

		jstring elem = env->NewStringUTF(json_results[i].c_str());
		env->SetObjectArrayElement(results,i,elem);
		env->DeleteLocalRef(elem);
都需要回收吗?
JNIEXPORT jstring JNICALL Java_com_sogou_ocr_OcrRecog_nativeGetVersion(JNIEnv *env, jclass cls)
{
	return env->NewStringUTF(SDKVERSION);
}

这种return的你怎么回收。

you should free them manually with DeleteLocalRef instead of letting JNI do it for you. 

也就是说JNI会自己回收,你只要别频繁超出就行。

总结

local reference系统会回收,但频繁创建需要自己回收(系统没来及)

参考资料

Google JNI tips

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值