AbstractStringBuilder.ensureCapacityInternal() doesn't need to copy the whole underlying array, only the part until the current count.
diff --git a/src/java.base/share/classes/java/lang/AbstractStringBuilder.java b/src/java.base/share/classes/java/lang/AbstractStringBuilder.java --- a/src/java.base/share/classes/java/lang/AbstractStringBuilder.java +++ b/src/java.base/share/classes/java/lang/AbstractStringBuilder.java @@ -140,11 +140,12 @@ * overflow, this method throws {@code OutOfMemoryError}. */ private void ensureCapacityInternal(int minimumCapacity) { + byte[] oldValue = value; // overflow-conscious code - int oldCapacity = value.length >> coder; + int oldCapacity = oldValue.length >> coder; if (minimumCapacity - oldCapacity > 0) { - value = Arrays.copyOf(value, - newCapacity(minimumCapacity) << coder); + value = new byte[newCapacity(minimumCapacity) << coder]; + System.arraycopy(oldValue, 0, value, 0, count << coder); } }