Trim thread local string builder if large

Motivation:

A previous change allocated a new thread local string builder if it
was getting too large. This is a good change, these string builders
can accidentally get too large and then never shrunk and that is sort
of a memory leak. However, the change allocates an entirely new string
builder which is more allocations than necessary. Instead, we can trim
the string builder if its too large, this only allocates an extra
backing array instead of a whole new object.

Modifications:

If the string builder is above a threshold, we trim the string builder
and then ensure its capacity is reasonable to we do not allocate too
much as we start using the string builder.

Result:

The thread local string builder do not serve as a memory yet we do not
allocate too many new objects.
This commit is contained in:
Jason Tedor 2017-05-05 15:30:03 -04:00 committed by Norman Maurer
parent 0db2901f4d
commit d88cd23bfc

View File

@ -35,7 +35,6 @@ import java.util.WeakHashMap;
*/
public final class InternalThreadLocalMap extends UnpaddedInternalThreadLocalMap {
private static final int STRING_BUILDER_MAX_CAPACITY = 1024 << 6;
private static final int DEFAULT_ARRAY_LIST_INITIAL_CAPACITY = 8;
public static final Object UNSET = new Object();
@ -164,13 +163,17 @@ public final class InternalThreadLocalMap extends UnpaddedInternalThreadLocalMap
}
public StringBuilder stringBuilder() {
StringBuilder builder = stringBuilder;
if (builder == null || builder.capacity() > STRING_BUILDER_MAX_CAPACITY) {
stringBuilder = builder = new StringBuilder(512);
final int stringBuilderCapacity = 1024;
if (stringBuilder == null) {
stringBuilder = new StringBuilder(stringBuilderCapacity);
} else {
builder.setLength(0);
if (stringBuilder.capacity() > stringBuilderCapacity) {
stringBuilder.setLength(stringBuilderCapacity);
stringBuilder.trimToSize();
}
stringBuilder.setLength(0);
}
return builder;
return stringBuilder;
}
public Map<Charset, CharsetEncoder> charsetEncoderCache() {