【问题标题】:How to fix JNI crash on env->NewObject?如何修复 env->NewObject 上的 JNI 崩溃?
【发布时间】:2013-11-10 08:38:24
【问题描述】:

我正在尝试通过 JNI (Clang C-API) 使用 Clang。 几次迭代后,它就会停止创建新对象并崩溃:

地图方法 0个参数: 创建方法实例 0x7fa26ba23c90 0x7fa26ba2a0c0 libclang: 崩溃 在索引源文件期间检测到:{'source_filename': '/Users/asmirnov/Documents/dev/src/clang_jni/mac/test/TestFile.h'
'command_line_args' : ['-c', '-x', 'c++'], 'unsaved_files' : [],
“选项”:0,}

代码非常简单:

mapMethod(JNIEnv *env, const CXIdxDeclInfo *info) {

    debug("map method");

    int numArgs = clang_Cursor_getNumArguments(info->cursor);
    debug("  %i args:", numArgs);

    debug("create Method instance %p %p", MethodClass, MethodConstructor);
    jobject result = env->NewObject(MethodClass, MethodConstructor);

    debug("create Method  params instance");

方法类和构造函数被正确地找到并注册为全局变量(似乎是),并且迭代次数很少:

// method
    MethodClass = (jclass)env->NewGlobalRef(env->FindClass("name/antonsmirnov/clang/dto/index/Method"));
    debug(MethodClass != NULL ? "found MethodClass" : "not found MethodClass");

    MethodConstructor = env->GetMethodID(MethodClass, "<init>", "()V");
    debug(MethodConstructor != NULL ? "found MethodConstructor" : "not found MethodConstructor");

我已经阅读了一些“jni 提示和技巧”文章并尝试env-&gt;DeleteLocalRef 并让本地引用计数太大而无法尝试,但没有结果:

// magic 
    jint ensureResult = env->EnsureLocalCapacity(1024);
    debug("ensure result %i", ensureResult);

    jint pushResult = env->PushLocalFrame(1024);
    debug("push result %i", pushResult);

Clang 正在劫持异常,所以我看不出真正的原因。 正如我所说,这个问题在几次迭代后发生,所以这似乎是一些超出限制的问题。

怎么了?

更新:我做了一些研究,发现如果我在此之前删除一些本地变量,我可以获得更多的迭代和更多的对象实例。所以它让我觉得它确实使用了 16 个本地变量,而忽略了我的 EnsureLocalCapacity 调用。应该在哪里做?

【问题讨论】:

    标签: java c++ c java-native-interface clang


    【解决方案1】:

    JNI_OnLoad() 中使用EnsureLocalCapacity 已修复(不适用于每个本机方法调用)。

    【讨论】:

    • 很难相信这有效。它应该只影响当前被调用的 JNI 方法。
    • 无论如何它都有效。 MBA-Anton:build asmirnov$ java -version java version "1.6.0_51" Java(TM) SE Runtime Environment (build 1.6.0_51-b11-457) Java HotSpot(TM) 64-Bit Server VM (build 20.51-b01- 457,混合模式),mac os 小牛
    【解决方案2】:

    通过NewObject、FindClass创建的对象,需要通过DeleteLocalRef()释放,因为jni中局部变量的数量是有限的。或者您可以在JNI_OnLoad() 中使用EnsureLocalCapacity

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-09-08
      • 1970-01-01
      • 2019-10-07
      • 2018-01-18
      • 2022-01-10
      • 2021-12-10
      • 1970-01-01
      相关资源
      最近更新 更多