Skip to content

Commit 2498fcc

Browse files
committed
fix: global object memory leak
1 parent 9546328 commit 2498fcc

File tree

2 files changed

+48
-7
lines changed

2 files changed

+48
-7
lines changed

dart_native/android/src/main/jni/dart_native.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,20 @@
99
#include "dn_method_call.h"
1010
#include "dn_signature_helper.h"
1111
#include "dn_callback.h"
12+
#include "jni_object_ref.h"
1213

1314
extern "C"
1415
{
1516

1617
static JavaVM *gJvm = nullptr;
17-
static jobject gClassLoader;
18+
static JavaGlobalRef<jobject> *gClassLoader = nullptr;
1819
static jmethodID gFindClassMethod;
1920
static pthread_key_t detachKey = 0;
2021

2122
/// for invoke result compare
22-
static jclass gStrCls;
23+
static JavaGlobalRef<jclass> *gStrCls = nullptr;
2324

24-
/// key is jobject, value is pai which contain jclass and reference count
25+
/// key is jobject, value is pair which contain jclass and reference count
2526
static std::map<jobject, std::pair<jclass, int> > objectGlobalReference;
2627

2728
/// protect objectGlobalReference
@@ -92,13 +93,13 @@ extern "C"
9293
auto getClassLoaderMethod = env->GetMethodID(pluginClass, "getClassLoader",
9394
"()Ljava/lang/ClassLoader;");
9495
auto classLoader = env->CallObjectMethod(plugin, getClassLoaderMethod);
95-
gClassLoader = env->NewGlobalRef(classLoader);
96+
gClassLoader = new JavaGlobalRef<jobject>(env->NewGlobalRef(classLoader), env);
9697
gFindClassMethod = env->GetMethodID(classLoaderClass, "findClass",
9798
"(Ljava/lang/String;)Ljava/lang/Class;");
9899

99100
/// cache string class
100101
jclass strCls = env->FindClass("java/lang/String");
101-
gStrCls = static_cast<jclass>(env->NewGlobalRef(strCls));
102+
gStrCls = new JavaGlobalRef<jclass>(static_cast<jclass>(env->NewGlobalRef(strCls)), env);
102103

103104
env->DeleteLocalRef(classLoader);
104105
env->DeleteLocalRef(plugin);
@@ -119,7 +120,7 @@ extern "C"
119120
{
120121
env->ExceptionClear();
121122
DNDebug("findClass exception");
122-
return static_cast<jclass>(env->CallObjectMethod(gClassLoader,
123+
return static_cast<jclass>(env->CallObjectMethod(gClassLoader->Object(),
123124
gFindClassMethod,
124125
env->NewStringUTF(name)));
125126
}
@@ -227,7 +228,7 @@ extern "C"
227228
jobject obj = env->CallObjectMethodA(object, method, argValues);
228229
if (obj != nullptr)
229230
{
230-
if (env->IsInstanceOf(obj, gStrCls))
231+
if (env->IsInstanceOf(obj, gStrCls->Object()))
231232
{
232233
/// mark the last pointer as string
233234
/// dart will check this pointer
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//
2+
// Created by Hui on 6/9/21.
3+
//
4+
5+
#ifndef DART_NATIVE_JNI_OBJECT_REF_H
6+
#define DART_NATIVE_JNI_OBJECT_REF_H
7+
8+
#include <jni.h>
9+
10+
/**
11+
* Global reference will auto delete in destructor
12+
*/
13+
template <typename T>
14+
class JavaGlobalRef {
15+
public:
16+
explicit JavaGlobalRef(T obj, JNIEnv *env): env_(env) {
17+
this->obj_ = env->NewGlobalRef(obj);
18+
}
19+
20+
JavaGlobalRef() = delete;
21+
22+
T Object() const { return static_cast<T>(obj_); }
23+
24+
~JavaGlobalRef() { this->DeleteGlobalRef(); }
25+
26+
protected:
27+
jobject obj_ = nullptr;
28+
29+
private:
30+
JNIEnv *env_;
31+
32+
void DeleteGlobalRef() {
33+
if (this->obj_) {
34+
env_->DeleteGlobalRef(this->obj_);
35+
this->obj_ = nullptr;
36+
}
37+
}
38+
};
39+
40+
#endif //DART_NATIVE_JNI_OBJECT_REF_H

0 commit comments

Comments
 (0)