1

这是示例 jni 方法,我在其中创建了一个字符串并将其返回给调用 java 方法:

jstring
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
                                                  jobject thiz )
{
    char test[100];
    sprintf(test, "Test%03d.txt", rand()/100);
    jstring returnVal = (*env)->NewStringUTF(env, test);
    (*env)->DeleteLocalRef(env,returnVal);
    return returnVal;
}

由于我删除了本地引用,因此我期望 jstring 在调用 java 方法中无效。但参考仍然有效。我明确调用 System.gc() 来查看 GC 是否清除它,但它没有发生。

据此:http ://android-developers.blogspot.com/2011/11/jni-local-reference-changes-in-ics.html

"Bug: Calling DeleteLocalRef() and continuing to use the deleted reference
It shouldn’t need to be said that it’s illegal to continue to use a reference after calling DeleteLocalRef() on it, but because it used to work, so you may have made this mistake and not realized. The usual pattern seems to be where native code has a long-running loop, and developers try to clean up every single local reference as they go to avoid hitting the local reference limit, but they accidentally also delete the reference they want to use as a return value!

The fix is trivial: don’t call DeleteLocalRef() on a reference you’re going to use (where “use” includes “return”)."

我对这种不一致感到有点困惑。

4

1 回答 1

2

您的目标是什么 SDK 级别?如果您的目标是 13 或更低(ICS 之前),那么您将获得旧的 JNI 行为,并且此代码应该可以工作(尽管它在技术上仍然不正确)

如果您的目标是 14 (ICS) 或更高,则显示的代码将失败并出现赠品错误:

memory map fault addr deadd00d

请注意,如果您以 SDK 14+ 为目标,但在较早版本的 Android 上运行该应用程序,该代码也可以工作

于 2013-06-06T16:39:41.380 回答