You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by mi...@apache.org on 2016/06/13 09:34:18 UTC
[22/33] logging-log4j2 git commit: LOG4J2-1417 added internal
representation that does not store non-JDK classes in ThreadLocals for safe
use in web applications
LOG4J2-1417 added internal representation that does not store non-JDK classes in ThreadLocals for safe use in web applications
Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/83b930dc
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/83b930dc
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/83b930dc
Branch: refs/heads/LOG4J2-1395
Commit: 83b930dcf07fe68a8220c452a34cb2385525096b
Parents: cff46e4
Author: rpopma <rp...@apache.org>
Authored: Sat Jun 11 17:20:51 2016 +0900
Committer: rpopma <rp...@apache.org>
Committed: Sat Jun 11 17:20:51 2016 +0900
----------------------------------------------------------------------
.../org/apache/logging/log4j/util/Unbox.java | 46 +++++++++++++++++++-
1 file changed, 45 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/83b930dc/log4j-api/src/main/java/org/apache/logging/log4j/util/Unbox.java
----------------------------------------------------------------------
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/util/Unbox.java b/log4j-api/src/main/java/org/apache/logging/log4j/util/Unbox.java
index 137a702..d0bb16f 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/util/Unbox.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/util/Unbox.java
@@ -52,6 +52,49 @@ public class Unbox {
private static final int RINGBUFFER_SIZE = calculateRingBufferSize("log4j.unbox.ringbuffer.size");
private static final int MASK = RINGBUFFER_SIZE - 1;
+ /**
+ * State implementation that only puts JDK classes in ThreadLocals, so this is safe to be used from
+ * web applications. Web application containers have thread pools that may hold on to ThreadLocal objects
+ * after the application was stopped. This may prevent the classes of the application from being unloaded,
+ * causing memory leaks.
+ * <p>
+ * Such memory leaks will not occur if only JDK classes are stored in ThreadLocals.
+ * </p>
+ */
+ private static class WebSafeState {
+ private final ThreadLocal<StringBuilder[]> ringBuffer = new ThreadLocal<>();
+ private final ThreadLocal<int[]> current = new ThreadLocal<>();
+
+ public StringBuilder getStringBuilder() {
+ StringBuilder[] array = ringBuffer.get();
+ if (array == null) {
+ array = new StringBuilder[RINGBUFFER_SIZE];
+ for (int i = 0; i < array.length; i++) {
+ array[i] = new StringBuilder(21);
+ }
+ ringBuffer.set(array);
+ current.set(new int[1]);
+ }
+ int[] index = current.get();
+ final StringBuilder result = array[MASK & index[0]++];
+ result.setLength(0);
+ return result;
+ }
+
+ public boolean isBoxedPrimitive(final StringBuilder text) {
+ StringBuilder[] array = ringBuffer.get();
+ if (array == null) {
+ return false;
+ }
+ for (int i = 0; i < array.length; i++) {
+ if (text == array[i]) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
private static class State {
private final StringBuilder[] ringBuffer = new StringBuilder[RINGBUFFER_SIZE];
private int current;
@@ -77,6 +120,7 @@ public class Unbox {
}
}
private static ThreadLocal<State> threadLocalState = new ThreadLocal<>();
+ private static WebSafeState webSafeState = new WebSafeState();
private Unbox() {
// this is a utility
@@ -218,7 +262,7 @@ public class Unbox {
}
private static StringBuilder getSB() {
- return getState().getStringBuilder();
+ return Constants.ENABLE_THREADLOCALS ? getState().getStringBuilder() : webSafeState.getStringBuilder();
}
/** For testing. */