From fb5036b7f12dd648340aaa7f90245afd353759e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Tue, 29 Oct 2013 17:40:56 +0100 Subject: Android: Fix problem with leaking local refs. In some cases we where not releasing the local references and since we no longer disconnect from the VM on each call, the number of local refs. would accumulating until it hit the hard-limit of 512. Change-Id: I6826620e4cb61a37af26d276667489e876080076 Reviewed-by: Yoann Lopes --- src/corelib/kernel/qjni.cpp | 29 ++++++++++++++++++++++------- src/corelib/kernel/qjni_p.h | 4 +++- src/corelib/kernel/qjnihelpers.cpp | 2 ++ 3 files changed, 27 insertions(+), 8 deletions(-) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qjni.cpp b/src/corelib/kernel/qjni.cpp index cf839cfaef..4e06d12aee 100644 --- a/src/corelib/kernel/qjni.cpp +++ b/src/corelib/kernel/qjni.cpp @@ -351,7 +351,9 @@ QJNIObjectPrivate::QJNIObjectPrivate(jobject obj) QJNIEnvironmentPrivate env; d->m_jobject = env->NewGlobalRef(obj); - d->m_jclass = static_cast(env->NewGlobalRef(env->GetObjectClass(d->m_jobject))); + jclass objectClass = env->GetObjectClass(d->m_jobject); + d->m_jclass = static_cast(env->NewGlobalRef(objectClass)); + env->DeleteLocalRef(objectClass); } template <> @@ -1262,7 +1264,10 @@ QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod(const char *methodName, if (id) { res = env->CallObjectMethodV(d->m_jobject, id, args); } - return res; + + QJNIObjectPrivate obj(res); + env->DeleteLocalRef(res); + return obj; } QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod(const char *methodName, @@ -1339,7 +1344,9 @@ QJNIObjectPrivate QJNIObjectPrivate::callStaticObjectMethod(const char *classNam } } - return res; + QJNIObjectPrivate obj(res); + env->DeleteLocalRef(res); + return obj; } QJNIObjectPrivate QJNIObjectPrivate::callStaticObjectMethod(const char *className, @@ -1366,7 +1373,9 @@ QJNIObjectPrivate QJNIObjectPrivate::callStaticObjectMethod(jclass clazz, res = env->CallStaticObjectMethodV(clazz, id, args); } - return res; + QJNIObjectPrivate obj(res); + env->DeleteLocalRef(res); + return obj; } QJNIObjectPrivate QJNIObjectPrivate::callStaticObjectMethod(jclass clazz, @@ -1678,7 +1687,9 @@ QJNIObjectPrivate QJNIObjectPrivate::getObjectField(const char *fieldName, if (id) res = env->GetObjectField(d->m_jobject, id); - return res; + QJNIObjectPrivate obj(res); + env->DeleteLocalRef(res); + return obj; } QJNIObjectPrivate QJNIObjectPrivate::getStaticObjectField(const char *className, @@ -1704,7 +1715,9 @@ QJNIObjectPrivate QJNIObjectPrivate::getStaticObjectField(jclass clazz, if (id) res = env->GetStaticObjectField(clazz, id); - return res; + QJNIObjectPrivate obj(res); + env->DeleteLocalRef(res); + return obj; } template <> @@ -2106,7 +2119,9 @@ QJNIObjectPrivate QJNIObjectPrivate::fromString(const QString &string) QJNIEnvironmentPrivate env; jstring res = env->NewString(reinterpret_cast(string.constData()), string.length()); - return res; + QJNIObjectPrivate obj(res); + env->DeleteLocalRef(res); + return obj; } QString QJNIObjectPrivate::toString() const diff --git a/src/corelib/kernel/qjni_p.h b/src/corelib/kernel/qjni_p.h index c5bbae26b9..ab98aec1bf 100644 --- a/src/corelib/kernel/qjni_p.h +++ b/src/corelib/kernel/qjni_p.h @@ -180,7 +180,9 @@ public: d = QSharedPointer(new QJNIObjectData()); QJNIEnvironmentPrivate env; d->m_jobject = env->NewGlobalRef(jobj); - d->m_jclass = static_cast(env->NewGlobalRef(env->GetObjectClass(jobj))); + jclass objectClass = env->GetObjectClass(jobj); + d->m_jclass = static_cast(env->NewGlobalRef(objectClass)); + env->DeleteLocalRef(objectClass); } return *this; diff --git a/src/corelib/kernel/qjnihelpers.cpp b/src/corelib/kernel/qjnihelpers.cpp index fbcd0606e6..9ec491f6a9 100644 --- a/src/corelib/kernel/qjnihelpers.cpp +++ b/src/corelib/kernel/qjnihelpers.cpp @@ -94,7 +94,9 @@ jint QtAndroidPrivate::initJNI(JavaVM *vm, JNIEnv *env) return JNI_ERR; g_jClassLoader = env->NewGlobalRef(classLoader); + env->DeleteLocalRef(classLoader); g_jActivity = env->NewGlobalRef(activity); + env->DeleteLocalRef(activity); g_javaVM = vm; return JNI_OK; -- cgit v1.2.3