Java JNI“;“本地参考表溢出”;使用NewGlobalRef时

Java JNI“;“本地参考表溢出”;使用NewGlobalRef时,java,android,c++,java-native-interface,Java,Android,C++,Java Native Interface,我正在开发一个使用JNI的应用程序,但在使用全局引用时出现“本地引用表溢出”错误: art/runtime/indirect_reference_table.cc:115] JNI ERROR (app bug): local reference table overflow (max=512) art/runtime/indirect_reference_table.cc:115] local reference table dump: art/runtime/indirect_refer

我正在开发一个使用JNI的应用程序,但在使用全局引用时出现“本地引用表溢出”错误:

art/runtime/indirect_reference_table.cc:115] JNI ERROR (app bug): local reference table overflow (max=512)
 art/runtime/indirect_reference_table.cc:115] local reference table dump:
 art/runtime/indirect_reference_table.cc:115]   Last 10 entries (of 508):
 art/runtime/indirect_reference_table.cc:115]       507: 0x13f08b80 com.company.util.jni.JniCompanyHelper$HTTPStream
 art/runtime/indirect_reference_table.cc:115]       506: 0x13ef5520 com.company.util.jni.JniCompanyHelper$HTTPStream
 art/runtime/indirect_reference_table.cc:115]       505: 0x13eb4a80 com.company.util.jni.JniCompanyHelper$HTTPStream
守则如下:

class Foo {
public:
    Foo(){}
    void doSomething(){
        JNIEnv* env = getEnv();
        javaObject = env->NewGlobalRef(env->CallStaticObjectMethod(...));
    }
    ~Foo() {
        JNIEnv* env = getEnv();
        env->DeleteGlobalRef(javaObject);
    }
private:
    jobject javaObject;
};

// ...
// Run the loop in a separate thread
for(int i =0; i< 1000; i++) {
    Foo foo;
    foo.doSomething();
}

有人知道我在这里缺少什么吗?

CallStaticObjectMethod返回对您正在创建的对象的本地引用(这意味着本地引用将添加到当前线程的本地引用表中)

除非返回java或从VM分离本机线程,否则该引用表不会被清除。如果继续创建本地引用而不清除本地引用表,那么最终将耗尽表中的可用项

您的固定版本会在您使用完每个本地引用后立即将其删除


全局引用的要点是,当您返回java或分离当前线程时,它们不会被自动删除,因此您以后可以使用相同的引用。但在您的例子中,您似乎不需要这样做,尽管您的示例看起来有点做作(您创建了从未使用过的对象)

这些例子被简化了。调用
Foo
析构函数时,它会调用
DeleteGlobalRef
,但从
env->CallStaticObjectMethod
返回的本地引用在创建全局引用后不会被删除。因此,修复方法只是在创建全局引用之后删除本地引用。谢谢您可能不希望在析构函数中无条件地调用
DeleteGlobalRef
,因为您可以在不创建全局引用的情况下构造
Foo
class Foo {
public:
    Foo(){}
    void doSomething(){
        JNIEnv* env = getEnv();
        jobject javaObject = env->CallStaticObjectMethod(...);
        env->DeleteLocalRef(javaObject);
    }
    ~Foo() {
    }
};