4

我有很多对象要在 c++ 上创建并将其发送到 java,我正在使用env->DeleteLocalRef(obj);但我收到以下错误:

06-10 18:43:56.976: E/dalvikvm(11536): JNI ERROR (app bug): local reference table overflow (max=512)
06-10 18:43:56.980: W/dalvikvm(11536): JNI local reference table (0x4d9c0b28) dump:
06-10 18:43:56.980: W/dalvikvm(11536):   Last 10 entries (of 512):
06-10 18:43:56.980: W/dalvikvm(11536):       511: 0x412bab68 java.lang.Class<la.jurema.moovebike.models.RoutePoint>
06-10 18:43:56.980: W/dalvikvm(11536):       510: 0x412bab68 java.lang.Class<la.jurema.moovebike.models.RoutePoint>
06-10 18:43:56.980: W/dalvikvm(11536):       509: 0x40e2a2a8 la.jurema.moovebike.models.RoutePoint[] (20 elements)
06-10 18:43:56.980: W/dalvikvm(11536):       508: 0x412bab68 java.lang.Class<la.jurema.moovebike.models.RoutePoint>
06-10 18:43:56.980: W/dalvikvm(11536):       507: 0x412bab68 java.lang.Class<la.jurema.moovebike.models.RoutePoint>
06-10 18:43:56.980: W/dalvikvm(11536):       506: 0x412de350 java.lang.Class<la.jurema.moovebike.models.BikeRoute>
06-10 18:43:56.980: W/dalvikvm(11536):       505: 0x412bab68 java.lang.Class<la.jurema.moovebike.models.RoutePoint>
06-10 18:43:56.980: W/dalvikvm(11536):       504: 0x412bab68 java.lang.Class<la.jurema.moovebike.models.RoutePoint>
06-10 18:43:56.980: W/dalvikvm(11536):       503: 0x412bab68 java.lang.Class<la.jurema.moovebike.models.RoutePoint>
06-10 18:43:56.980: W/dalvikvm(11536):       502: 0x412bab68 java.lang.Class<la.jurema.moovebike.models.RoutePoint>
06-10 18:43:56.980: W/dalvikvm(11536):   Summary:
06-10 18:43:56.980: W/dalvikvm(11536):       505 of java.lang.Class (7 unique instances)
06-10 18:43:56.980: W/dalvikvm(11536):         3 of java.lang.String (3 unique instances)
06-10 18:43:56.980: W/dalvikvm(11536):         1 of java.lang.String[] (2 elements)
06-10 18:43:56.980: W/dalvikvm(11536):         1 of la.jurema.moovebike.network.DataDownloadResponseAbstract
06-10 18:43:56.980: W/dalvikvm(11536):         1 of la.jurema.moovebike.models.BikeRoute[] (15 elements)
06-10 18:43:56.980: W/dalvikvm(11536):         1 of la.jurema.moovebike.models.RoutePoint[] (20 elements)
06-10 18:43:56.980: E/dalvikvm(11536): Failed adding to JNI local ref table (has 512 entries)

我不知道这是什么意思java.lang.Class......我该如何解决这个问题?增加参考表?或者我没有删除什么?

4

3 回答 3

6

您需要删除对类和对象的本地引用。

于 2013-06-10T22:11:14.330 回答
4

看起来你得到了很多java.lang.Class. 获得这些的最常见方法是调用FindClass. <> 尖括号中的名称是被查找的类的名称,因此您应该寻找在RoutePoint或上进行查找的地方BikeRoute

FindClass可能相当昂贵,因此对于经常使用的类,您希望在初始化期间调用它并缓存结果(作为全局参考)以供以后使用。

如果您在循环中运行,最好显式删除返回的任何对象的本地引用。在 Dalvik 中无法将本地引用表扩展到 512 个条目之外。

另请参阅JNI 提示文档。

于 2013-06-10T22:21:47.173 回答
0

如果不是非常冗长,我发现以下技术很有用,我创建了一个名为 Guardian 的类,如下所示:

/*
 * Guardian.h
 *
 *  Created on: Jul 14, 2014
 *      Author: yaturner
 */
#ifndef GUARDIAN_H_
#define GUARDIAN_H_

#define GLOGD(...) __android_log_print(ANDROID_LOG_DEBUG, tagName, __VA_ARGS__ )

{

class Guardian
{
private:
    char* funcName;
    char* tagName;

public:
    Guardian(const char*, const char*);
    virtual ~Guardian();
};

#endif /* GUARDIAN_H_ */

/*
 * Guardian.cpp
 *
 *  Created on: Jul 14, 2014
 *      Author: yaturner
 */
#include "Guardian.h"

Guardian(const char* func, const char* tag)
{
    int len = strlen(func);
    funcName = new char[len+1];
    strcpy(funcName, func);
    len = strlen(func);
    tagName = new char[len+1];
    strcpy(tagName, tag);
    GLOGD("Entering %s", funcName);
}

~Guardian()
{
    GLOGD("Exiting %s", funcName);
    dumpLocalRefTable();
    free(funcName);
    free(tagName);

}

void dumpLocalRefTable()
{
    JNIEnv* env = preamble(); 
    jclass vm_class = env->FindClass("dalvik/system/VMDebug");
    jmethodID dump_mid = env->GetStaticMethodID( vm_class, "dumpReferenceTables", "()V" );
    env->CallStaticVoidMethod( vm_class, dump_mid );

    env->DeleteLocalRef(vm_class);
}

然后在我的每个 JNI 方法开始时,我实例化了 Guardian 类,我得到的是一个巨大的 logcat,其中包含每个方法的入口和出口以及 ref 表。通过检查日志,我可以查找表中的更改并确定导致它们的方法。痛苦,但它奏效了。

于 2014-08-13T18:57:04.737 回答