首先声明这个问题是在Android系统中进行
之前在做NDK开发时,自然少不了
workerThread = std::thread([this]()
{
g_pVM->AttachCurrentThread(&mJNIEnv, NULL);
...
g_pVM->DetachCurrentThread();
}
);
并在线程中进行了Java方法的调用,传递了一些字符串,结果没跑几个循环进程就crash掉了,看了下logcat提示的错误是:
JNI ERROR (app bug): local reference table overflow (max=512)
并打印出了最后200个local reference table中的东西,看了下有传的String有get到的Java class,于是想到了释放引用的问题,不过JNI调用的代码都是copy过来以前写的,也没出现过类似的问题,很是奇怪。
看着table里的东西把该release的都release了,用完了的object都DeleteLocalRef了,再运行了几次果然不再crash了。看来对JNI的理解需要加强一下了,开始寻找资料,最后在谷沟Android开发官网找到的一篇JNI Tips(链接见下方)中找到了相关信息:
One unusual case deserves separate mention. If you attach a native AttachCurrentThread, the code you are running will never automatically free local references until the thread detaches. Any local references you create will have to be deleted manually. In general, any native code that creates local references in a loop probably needs to do some manual deletion.
原来native代码中创建线程并attach出的JNIEnv不会自动释放局部引用,直到detach,所以如果这之间的ref没太多的,以至于超过max=512的话,撑到detach也就释放相安无事了,但要是像我这样有个循环不停的进行JNI调用的话肯定没一会就超额了,所以必要的手动释放ref还是要加上的。
参考:
文字加密小工具v3
请输入要加密的内容
博主友情提示:
如您在评论中需要提及如QQ号、电子邮件地址或其他隐私敏感信息,欢迎使用