You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2017/07/16 20:46:05 UTC

[2/3] httpcomponents-client git commit: [HTTPCLIENT-1858] Clone some code from Log4j 2 to cache a StringBuilder in a ThreadLocal.

[HTTPCLIENT-1858] Clone some code from Log4j 2 to cache a StringBuilder in a ThreadLocal.


Project: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/commit/527dce78
Tree: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/tree/527dce78
Diff: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/diff/527dce78

Branch: refs/heads/master
Commit: 527dce78a7950509fc9e301f405a9da268b7006d
Parents: 49989d8
Author: Gary Gregory <gg...@apache.org>
Authored: Sun Jul 16 12:01:54 2017 -0700
Committer: Oleg Kalnichevski <ol...@apache.org>
Committed: Sun Jul 16 22:42:16 2017 +0200

----------------------------------------------------------------------
 RELEASE_NOTES.txt                               |  4 ++-
 .../hc/client5/http/impl/logging/Wire.java      | 38 +++++++++++++++++++-
 2 files changed, 40 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/527dce78/RELEASE_NOTES.txt
----------------------------------------------------------------------
diff --git a/RELEASE_NOTES.txt b/RELEASE_NOTES.txt
index dbbf0a0..a0dd7d4 100644
--- a/RELEASE_NOTES.txt
+++ b/RELEASE_NOTES.txt
@@ -1,10 +1,12 @@
-Release 5.0-ALPHA3
+Release 5.0-ALPHA3
 -------------------
 
 * [HTTPCLIENT-1845]: Extract InputStreamFactory classes out of GzipDecompressingEntity and 
   DeflateDecompressingEntity for reuse and to create less garbage.
   Contributed by Gary Gregory <ggregory at apache.org>
 
+* [HTTPCLIENT-1858] Alleviate GC pressure due to wire logging.
+
 
 Release 5.0-ALPHA2
 -------------------

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/527dce78/httpclient5/src/main/java/org/apache/hc/client5/http/impl/logging/Wire.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/logging/Wire.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/logging/Wire.java
index a3abb5e..e6b09b1 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/logging/Wire.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/logging/Wire.java
@@ -34,6 +34,42 @@ import org.apache.logging.log4j.Logger;
 
 class Wire {
 
+    private static final int MAX_STRING_BUILDER_SIZE = 2048;
+
+    private static final ThreadLocal<StringBuilder> threadLocal = new ThreadLocal<>();
+
+    /**
+     * Returns a {@code StringBuilder} that this Layout implementation can use to write the formatted log event to.
+     *
+     * @return a {@code StringBuilder}
+     */
+    private static StringBuilder getStringBuilder() {
+        StringBuilder result = threadLocal.get();
+        if (result == null) {
+            result = new StringBuilder(MAX_STRING_BUILDER_SIZE);
+            threadLocal.set(result);
+        }
+        // TODO Delegate to Log4j's 2.9 StringBuilds.trimToMaxSize() when it is released.
+        trimToMaxSize(result, MAX_STRING_BUILDER_SIZE);
+        result.setLength(0);
+        return result;
+    }
+
+    /**
+     * Ensures that the char[] array of the specified StringBuilder does not exceed the specified number of characters.
+     * This method is useful to ensure that excessively long char[] arrays are not kept in memory forever.
+     *
+     * @param stringBuilder the StringBuilder to check
+     * @param maxSize the maximum number of characters the StringBuilder is allowed to have
+     */
+    // TODO Delete wheb Log4j's 2.9 (see #trimToMaxSize(StringBuild))
+    private static void trimToMaxSize(final StringBuilder stringBuilder, final int maxSize) {
+        if (stringBuilder != null && stringBuilder.length() > maxSize) {
+            stringBuilder.setLength(maxSize);
+            stringBuilder.trimToSize();
+        }
+    }
+
     private final Logger log;
     private final String id;
 
@@ -44,7 +80,7 @@ class Wire {
     }
 
     private void wire(final String header, final byte[] b, final int pos, final int off) {
-        final StringBuilder buffer = new StringBuilder();
+        final StringBuilder buffer = getStringBuilder();
         for (int i = 0; i < off; i++) {
             final int ch = b[pos + i];
             if (ch == 13) {