扩容最核心开销是Arrays.copyOf的O(n)内存拷贝,发生在容量校验后:先判断count+新增字符数>value.length即触发,再按newCapacity=(oldCapacity<<1)+2与最小需容量取大者确定新大小,最后复制前count个有效字符。

StringBuilder 扩容时的数组复制,是整个扩容过程中最核心、开销最大的一步,本质就是一次确定性的内存拷贝操作。
扩容前先做容量校验
每次调用 append、insert 或 replace 时,JVM 都会在执行实际逻辑前检查:
当前已用长度(count) + 即将新增字符数 > 底层数组长度(value.length)
只要成立,立刻进入扩容流程,不是等操作做完才发现不够。
新数组怎么分配
扩容不是简单翻倍,而是分步算出目标大小:
- 先算最小需要容量:minimumCapacity = count + 新增字符数
- 再按公式算基础容量:newCapacity = (oldCapacity << 1) + 2(即旧容量 × 2 + 2)
- 最终容量取两者较大值:Math.max(minimumCapacity, newCapacity)
- 还要校验上限:不能超过 Integer.MAX_VALUE - 8,否则抛 OutOfMemoryError
复制过程就是 Arrays.copyOf
确定好新容量后,底层直接调用:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- Arrays.copyOf(value, newCapacity)(JDK 8 及之前)
- 或等价的 System.arraycopy(value, 0, newValue, 0, count)(更底层实现)
这个操作会把 旧数组中前 count 个有效字符 完整复制到新数组开头,其余位置默认填充 \u0000。复制完成后,内部 value 引用被指向新数组,旧数组失去引用,等待 GC 回收。
立即学习“Java免费学习笔记(深入)”;
为什么这步开销大
因为它是 O(n) 时间复杂度 的内存操作:
- n 是当前已存的有效字符数(count),不是新容量
- Arrays.copyOf 是热点方法,基本说明 StringBuilder 预分配不足、扩容太勤

















