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

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 クラスをインスタンス化しました。取得したのは、各メソッドのエントリと終了、および ref テーブルを含む大量の logcat でした。ログを調べることで、テーブル内の変更を探し、その原因となったメソッドを特定できました。痛いけど効きました。

于 2014-08-13T18:57:04.737 に答える