【问题标题】:Correct usage of DeleteLocalRef in JNIJNI中DeleteLocalRef的正确使用
【发布时间】:2013-05-20 23:28:37
【问题描述】:

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

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”)."

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

【问题讨论】:

    标签: java android reference garbage-collection java-native-interface


    【解决方案1】:

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

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

    memory map fault addr deadd00d
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-02
      • 2019-05-21
      • 2012-10-14
      相关资源
      最近更新 更多