Skip to content

Commit b58c554

Browse files
committed
Java: Option to detach from the JVM in the thread destructor.
1 parent 1ad77e8 commit b58c554

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

CHANGES.current

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,16 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
77
Version 4.1.0 (in progress)
88
===========================
99

10+
2022-05-23: jkuebart
11+
[Java] On some versions of Android, specifically Android 6,
12+
detaching the current thread from the JVM after every invocation
13+
causes a memory leak.
14+
15+
Offer SWIG_JAVA_DETACH_ON_THREAD_END to configure a behaviour
16+
where the JVM is only detached in the thread destructor.
17+
18+
See https://developer.android.com/training/articles/perf-jni#threads.
19+
1020
2022-05-15: erezgeva, eiselekd
1121
[Lua, Perl, Octave, PHP, Tcl] #2275 #2276 #2283 Add argcargv.i library containing
1222
(int ARGC, char **ARGV) multi-argument typemaps.

Lib/java/director.swg

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,22 @@ SWIGINTERN int Swig::GetThreadName(char *name, size_t len) {
5151

5252
#endif
5353

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+
5470
namespace Swig {
5571

5672
/* Java object wrapper */
@@ -201,9 +217,19 @@ namespace Swig {
201217
#else
202218
director_->swig_jvm_->AttachCurrentThread(jenv, &args);
203219
#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
204230
}
205231
~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)
207233
// Some JVMs, eg jdk-1.4.2 and lower on Solaris have a bug and crash with the DetachCurrentThread call.
208234
// However, without this call, the JVM hangs on exit when the thread was not created by the JVM and creates a memory leak.
209235
if (env_status == JNI_EDETACHED)

0 commit comments

Comments
 (0)