Make configurable the initial and max size of InternalThreadLocalMap#stringBuilder

Motivation:
In some cases of using an `InternalThreadLocalMap#stringBuilder`, the `StringBuilder`s size can often exceed the exist limit (1024 bytes). This can lead to permanent memory reallocation.

Modifications:
Add custom properties for the initial capacity and maximum size (after which the `StringBuilder`s capacity will be reduced to the initial capacity).

Result:
An `InternalThreadLocalMap#stringBuilder`s initial and max size is configurable. Fixes [#7092].
This commit is contained in:
Nikolay Fedorovskikh 2017-08-14 21:33:57 +05:00 committed by Scott Mitchell
parent 505993a2fb
commit e249b453a0

View File

@ -18,6 +18,8 @@ package io.netty.util.internal;
import io.netty.util.concurrent.FastThreadLocal;
import io.netty.util.concurrent.FastThreadLocalThread;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
@ -35,10 +37,23 @@ import java.util.WeakHashMap;
*/
public final class InternalThreadLocalMap extends UnpaddedInternalThreadLocalMap {
private static final InternalLogger logger = InternalLoggerFactory.getInstance(InternalThreadLocalMap.class);
private static final int DEFAULT_ARRAY_LIST_INITIAL_CAPACITY = 8;
private static final int STRING_BUILDER_INITIAL_SIZE;
private static final int STRING_BUILDER_MAX_SIZE;
public static final Object UNSET = new Object();
static {
STRING_BUILDER_INITIAL_SIZE =
SystemPropertyUtil.getInt("io.netty.threadLocalMap.stringBuilder.initialSize", 1024);
logger.debug("-Dio.netty.threadLocalMap.stringBuilder.initialSize: {}", STRING_BUILDER_INITIAL_SIZE);
STRING_BUILDER_MAX_SIZE = SystemPropertyUtil.getInt("io.netty.threadLocalMap.stringBuilder.maxSize", 1024 * 4);
logger.debug("-Dio.netty.threadLocalMap.stringBuilder.maxSize: {}", STRING_BUILDER_MAX_SIZE);
}
public static InternalThreadLocalMap getIfSet() {
Thread thread = Thread.currentThread();
if (thread instanceof FastThreadLocalThread) {
@ -163,17 +178,16 @@ public final class InternalThreadLocalMap extends UnpaddedInternalThreadLocalMap
}
public StringBuilder stringBuilder() {
final int stringBuilderCapacity = 1024;
if (stringBuilder == null) {
stringBuilder = new StringBuilder(stringBuilderCapacity);
} else {
if (stringBuilder.capacity() > stringBuilderCapacity) {
stringBuilder.setLength(stringBuilderCapacity);
stringBuilder.trimToSize();
StringBuilder sb = stringBuilder;
if (sb == null) {
return stringBuilder = new StringBuilder(STRING_BUILDER_INITIAL_SIZE);
}
stringBuilder.setLength(0);
if (sb.capacity() > STRING_BUILDER_MAX_SIZE) {
sb.setLength(STRING_BUILDER_INITIAL_SIZE);
sb.trimToSize();
}
return stringBuilder;
sb.setLength(0);
return sb;
}
public Map<Charset, CharsetEncoder> charsetEncoderCache() {