@@ -51,6 +51,22 @@ SWIGINTERN int Swig::GetThreadName(char *name, size_t len) {
51
51
52
52
#endif
53
53
54
+ #if defined(SWIG_JAVA_DETACH_ON_THREAD_END)
55
+ #include <pthread.h>
56
+ namespace {
57
+
58
+ void detach(void* jvm) {
59
+ static_cast<JavaVM*>(jvm)->DetachCurrentThread();
60
+ }
61
+
62
+ pthread_key_t detachKey;
63
+ void makeDetachKey() {
64
+ pthread_key_create(&detachKey, detach);
65
+ }
66
+
67
+ }
68
+ #endif
69
+
54
70
namespace Swig {
55
71
56
72
/* Java object wrapper */
@@ -201,9 +217,19 @@ namespace Swig {
201
217
#else
202
218
director_->swig_jvm_->AttachCurrentThread(jenv, &args);
203
219
#endif
220
+
221
+ #if defined(SWIG_JAVA_DETACH_ON_THREAD_END)
222
+ // At least on Android 6, detaching after every call causes a memory leak.
223
+ // Instead, register a thread desructor and detach only when the thread ends.
224
+ // See https://developer.android.com/training/articles/perf-jni#threads
225
+ static pthread_once_t once = PTHREAD_ONCE_INIT;
226
+
227
+ pthread_once(&once, makeDetachKey);
228
+ pthread_setspecific(detachKey, director->swig_jvm_);
229
+ #endif
204
230
}
205
231
~JNIEnvWrapper() {
206
- #if !defined(SWIG_JAVA_NO_DETACH_CURRENT_THREAD)
232
+ #if !defined(SWIG_JAVA_DETACH_ON_THREAD_END) && !defined( SWIG_JAVA_NO_DETACH_CURRENT_THREAD)
207
233
// Some JVMs, eg jdk-1.4.2 and lower on Solaris have a bug and crash with the DetachCurrentThread call.
208
234
// However, without this call, the JVM hangs on exit when the thread was not created by the JVM and creates a memory leak.
209
235
if (env_status == JNI_EDETACHED)
0 commit comments