forked from organicmaps/organicmaps
Fixed crash with jni localreference table overflow after updating large number of outdated maps.
This commit is contained in:
parent
23e5564bf3
commit
d2748b12c7
3 changed files with 44 additions and 14 deletions
|
@ -81,6 +81,9 @@ namespace jni
|
|||
|
||||
jmethodID mid = env->GetMethodID(cls, fn, sig);
|
||||
ASSERT(mid, ("Can't get methodID", fn, sig, DescribeException()));
|
||||
|
||||
env->DeleteLocalRef(cls);
|
||||
|
||||
return mid;
|
||||
}
|
||||
|
||||
|
@ -219,4 +222,18 @@ namespace jni
|
|||
static_cast<jint>(point.x),
|
||||
static_cast<jint>(point.y));
|
||||
}
|
||||
|
||||
// TODO
|
||||
// make ScopedLocalRef wrapper similar to https://android.googlesource.com/platform/libnativehelper/+/jb-mr1.1-dev-plus-aosp/include/nativehelper/ScopedLocalRef.h
|
||||
// for localrefs automatically removed after going out of scope
|
||||
|
||||
// This util method dumps content of local and global reference jni tables to logcat for debug and testing purposes
|
||||
void DumpDalvikReferenceTables()
|
||||
{
|
||||
JNIEnv * env = jni::GetEnv();
|
||||
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);
|
||||
}
|
||||
} // namespace jni
|
||||
|
|
|
@ -47,4 +47,6 @@ namespace jni
|
|||
|
||||
jobject GetNewPoint(JNIEnv * env, m2::PointD const & point);
|
||||
jobject GetNewPoint(JNIEnv * env, m2::PointI const & point);
|
||||
|
||||
void DumpDalvikReferenceTables();
|
||||
}
|
||||
|
|
|
@ -24,8 +24,8 @@ public:
|
|||
jclass klass = env->FindClass("com/mapswithme/maps/downloader/DownloadChunkTask");
|
||||
ASSERT ( klass, () );
|
||||
|
||||
jmethodID methodId = env->GetMethodID(klass, "<init>", "(JLjava/lang/String;JJJ[BLjava/lang/String;)V");
|
||||
ASSERT ( methodId, () );
|
||||
static jmethodID initMethodId = env->GetMethodID(klass, "<init>", "(JLjava/lang/String;JJJ[BLjava/lang/String;)V");
|
||||
ASSERT ( initMethodId, () );
|
||||
|
||||
// User id is always the same, so do not waste time on every chunk call
|
||||
static string uniqueUserId = GetPlatform().UniqueClientId();
|
||||
|
@ -37,21 +37,32 @@ public:
|
|||
postBody = env->NewByteArray(postBodySize);
|
||||
env->SetByteArrayRegion(postBody, 0, postBodySize, reinterpret_cast<jbyte const *>(pb.c_str()));
|
||||
}
|
||||
m_self = env->NewGlobalRef(env->NewObject(klass,
|
||||
methodId,
|
||||
reinterpret_cast<jlong>(&cb),
|
||||
env->NewStringUTF(url.c_str()),
|
||||
static_cast<jlong>(beg),
|
||||
static_cast<jlong>(end),
|
||||
static_cast<jlong>(expectedFileSize),
|
||||
postBody,
|
||||
env->NewStringUTF(uniqueUserId.c_str())));
|
||||
|
||||
jstring jUrl = env->NewStringUTF(url.c_str());
|
||||
jstring jUserId = env->NewStringUTF(uniqueUserId.c_str());
|
||||
jobject const localSelf = env->NewObject(klass,
|
||||
initMethodId,
|
||||
reinterpret_cast<jlong>(&cb),
|
||||
jUrl,
|
||||
static_cast<jlong>(beg),
|
||||
static_cast<jlong>(end),
|
||||
static_cast<jlong>(expectedFileSize),
|
||||
postBody,
|
||||
jUserId);
|
||||
m_self = env->NewGlobalRef(localSelf);
|
||||
ASSERT ( m_self, () );
|
||||
|
||||
methodId = env->GetMethodID(klass, "start", "()V");
|
||||
ASSERT ( methodId, () );
|
||||
env->DeleteLocalRef(localSelf);
|
||||
env->DeleteLocalRef(postBody);
|
||||
env->DeleteLocalRef(jUrl);
|
||||
env->DeleteLocalRef(jUserId);
|
||||
|
||||
env->CallVoidMethod(m_self, methodId);
|
||||
static jmethodID startMethodId = env->GetMethodID(klass, "start", "()V");
|
||||
ASSERT ( startMethodId, () );
|
||||
|
||||
env->DeleteLocalRef(klass);
|
||||
|
||||
env->CallVoidMethod(m_self, startMethodId);
|
||||
}
|
||||
|
||||
~HttpThread()
|
||||
|
|
Loading…
Add table
Reference in a new issue