aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Sohn <matthias.sohn@sap.com>2018-01-08 10:40:23 +0100
committerMatthias Sohn <matthias.sohn@sap.com>2018-02-14 21:39:25 +0100
commit95fc2b210f3df3a1ff5c729dbc0624e3d25d34bd (patch)
tree4cc9fcb6b6c216025abaf0443b12591aade389b1
parent95f868f2463ed9de814cff8dbd8f0f90965d4c63 (diff)
downloadjgit-95fc2b210f3df3a1ff5c729dbc0624e3d25d34bd.tar.gz
jgit-95fc2b210f3df3a1ff5c729dbc0624e3d25d34bd.zip
Don't subclass ThreadLocal to avoid memory leak in NLS
These problem usually occur when you subclass ThreadLocal (usually to implement initialValue). Those classes reference the webapp's classloader. The ThreadLocal subclass in turn is referenced by each Thread instance (that's how ThreadLocals are implemented, they have a "helper-Map" in each Thread instance, so the leak is actually not a tiny Random instance but the whole webapp's classloader with a bunch of class definitions and statically referenced parts of the webapp. Bug: 449321 Change-Id: Ie7a8b0b90e40229e2471202f2a12637b9e0b1d11 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/nls/NLS.java26
1 files changed, 17 insertions, 9 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/nls/NLS.java b/org.eclipse.jgit/src/org/eclipse/jgit/nls/NLS.java
index 3c0d839dfb..89a87af9eb 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/nls/NLS.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/nls/NLS.java
@@ -74,12 +74,7 @@ public class NLS {
*/
public static final Locale ROOT_LOCALE = new Locale("", "", ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- private static final InheritableThreadLocal<NLS> local = new InheritableThreadLocal<NLS>() {
- @Override
- protected NLS initialValue() {
- return new NLS(Locale.getDefault());
- }
- };
+ private static final InheritableThreadLocal<NLS> local = new InheritableThreadLocal<>();
/**
* Sets the locale for the calling thread.
@@ -99,10 +94,19 @@ public class NLS {
/**
* Sets the JVM default locale as the locale for the calling thread.
* <p>
- * Semantically this is equivalent to <code>NLS.setLocale(Locale.getDefault())</code>.
+ * Semantically this is equivalent to
+ * <code>NLS.setLocale(Locale.getDefault())</code>.
*/
public static void useJVMDefaultLocale() {
- local.set(new NLS(Locale.getDefault()));
+ useJVMDefaultInternal();
+ }
+
+ // TODO(ms): change signature of public useJVMDefaultLocale() in 5.0 to get
+ // rid of this internal method
+ private static NLS useJVMDefaultInternal() {
+ NLS b = new NLS(Locale.getDefault());
+ local.set(b);
+ return b;
}
/**
@@ -122,7 +126,11 @@ public class NLS {
* {@link org.eclipse.jgit.errors.TranslationStringMissingException}
*/
public static <T extends TranslationBundle> T getBundleFor(Class<T> type) {
- return local.get().get(type);
+ NLS b = local.get();
+ if (b == null) {
+ b = useJVMDefaultInternal();
+ }
+ return b.get(type);
}
final private Locale locale;