From 876a168f6757454e8a02543b53e32b89e54282bd Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Mon, 28 Jul 2014 00:47:33 +0200 Subject: Bug 1029 - Memory leak in GLDrawableHelper: 'perThreadInitAction' shall use a WeakReference Static ThreadLocal 'perThreadInitAction' leaks memory if using a hard reference, utilizing a WeakReference allows the passed 'initAction' owner to be garbage collected. --- .../classes/jogamp/opengl/GLDrawableHelper.java | 27 +++++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) (limited to 'src/jogl/classes/jogamp/opengl') diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java index ad1b9a556..7d05174ce 100644 --- a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java +++ b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java @@ -40,6 +40,7 @@ package jogamp.opengl; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; import java.util.HashSet; @@ -1066,7 +1067,21 @@ public class GLDrawableHelper { return exclusiveContextThread; } - private static final ThreadLocal perThreadInitAction = new ThreadLocal(); + private static final ThreadLocal> perThreadInitAction = new ThreadLocal>(); + private static final Runnable getLastInitAction() { + final WeakReference lastInitActionWR = perThreadInitAction.get(); + if( null != lastInitActionWR ) { + final Runnable lastInitAction = lastInitActionWR.get(); + if( null == lastInitAction ) { + perThreadInitAction.set(null); + } + return lastInitAction; + } + return null; + } + private static final void setLastInitAction(final Runnable initAction) { + perThreadInitAction.set(new WeakReference(initAction)); + } /** Principal helper method which runs a Runnable with the context made current. This could have been made part of GLContext, but a @@ -1128,7 +1143,7 @@ public class GLDrawableHelper { lastContext = null; } else { // utilize recursive locking - lastInitAction = perThreadInitAction.get(); + lastInitAction = getLastInitAction(); lastContext.release(); } } @@ -1202,7 +1217,7 @@ public class GLDrawableHelper { lastContext = null; } else { // utilize recursive locking - lastInitAction = perThreadInitAction.get(); + lastInitAction = getLastInitAction(); lastContext.release(); } } @@ -1217,7 +1232,7 @@ public class GLDrawableHelper { } if (GLContext.CONTEXT_NOT_CURRENT != res) { try { - perThreadInitAction.set(initAction); + setLastInitAction(initAction); if (GLContext.CONTEXT_CURRENT_NEW == res) { if (DEBUG) { System.err.println("GLDrawableHelper " + this + ".invokeGL(): Running initAction"); @@ -1291,7 +1306,7 @@ public class GLDrawableHelper { lastContext = null; } else { // utilize recursive locking - lastInitAction = perThreadInitAction.get(); + lastInitAction = getLastInitAction(); lastContext.release(); } } @@ -1315,7 +1330,7 @@ public class GLDrawableHelper { } if (GLContext.CONTEXT_NOT_CURRENT != res) { try { - perThreadInitAction.set(initAction); + setLastInitAction(initAction); if (GLContext.CONTEXT_CURRENT_NEW == res) { if (DEBUG) { System.err.println("GLDrawableHelper " + this + ".invokeGL(): Running initAction"); -- cgit v1.2.3