I have a lot of objects to create on c++ and send it to java, I'm using the env->DeleteLocalRef(obj);
but I'm getting the following error:
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)
I dont know what means this java.lang.Class
... how I can solve this? Increase the reference table? Or what I'm not deleting?
您需要删除对类和对象的本地引用。
It looks like you're getting lots of instances of java.lang.Class
. The most common way to get these is by calling FindClass
. The name in the <> angle brackets is the name of the class that was looked up, so you should be looking for places where you do a lookup on RoutePoint
or BikeRoute
.
FindClass
can be fairly expensive, so for frequently-used classes you want to call that during initialization and cache the result (as a global reference) for later use.
If you're running in a loop, it's a good idea to explicitly delete the local reference for any object returned. Expanding the local reference table beyond 512 entries isn't possible in Dalvik.
See also the JNI Tips document.
I found the following technique useful if not horribly verbose, I created a class called Guardian as follows:
/*
* 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_ */
and
/*
* 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);
}
and
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);
}
Then at the beginning of each of my JNI methods I instanciated the Guardian class, what I got was a massive logcat with each method entry and exit plus the ref table. By examining the log I could look for changes in the table and determine what method caused them. Painful but it worked.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.