trimToSize将StringBuilder底层数组容量缩减至当前length,释放冗余内存;适用于拼接完成、长期只读或内存敏感场景,调用后不改变内容且后续append仍可扩容。

trimToSize 不会释放“多余内存”,它只是将底层数组容量缩小到当前字符串长度,仅当当前容量明显大于实际字符数时才有意义。
trimToSize 的真实作用
StringBuilder 内部维护一个 char 数组(JDK 8)或 int 数组(JDK 9+,支持 Latin-1 优化),其容量(capacity)通常大于当前字符数量(length)。trimToSize 方法会检查:如果当前数组长度 > 当前字符数,则新建一个恰好容纳 length 个字符的数组,并把内容复制过去;否则什么也不做。
- 它不涉及 JVM 垃圾回收,只是减少对象持有的数组大小
- 原数组若无其他引用,后续由 GC 回收——但这是 GC 的事,不是 trimToSize 的责任
- 调用后 capacity == length,不再预留扩展空间
什么时候调用才有效?
只有在 StringBuilder 经历过大幅扩容(如大量 append 后又 clear 或 setLength(0)),但后续不再增长时,trimToSize 才有节省内存的价值。
- 例如:构建一个最终长度为 100 的字符串,但中间曾 append 到 5000,再清空重用 → 此时 capacity 可能仍是 5000+,trimToSize 可缩回 100
- 如果刚 new StringBuilder() 就 append("abc"),然后 trimToSize(),几乎没效果(默认初始容量 16,length=3,缩到 3 意义不大)
- 频繁调用反而可能增加复制开销,尤其对短字符串
如何正确使用?
典型适用场景是“一次性构建 + 长期持有”——比如缓存拼接结果、配置生成、模板渲染后的固定字符串。
立即学习“Java免费学习笔记(深入)”;
- 构建完成后立即调用:sb.append(...).append(...); sb.trimToSize();
- 避免在循环中反复调用,尤其配合 clear() 使用时需谨慎(clear 后 length=0,trimToSize 会缩成空数组,下次 append 又要扩容)
- 替代思路:若明确知道最终长度,可用 new StringBuilder(int capacity) 预分配,比 trimToSize 更高效
注意 JDK 版本差异
JDK 9 引入压缩字符串优化(compact strings),底层可能用 byte[] 存储纯 Latin-1 字符。trimToSize 依然按字符数截取,但实际内存占用还取决于编码内容和 JVM 参数(如 -XX:+UseCompressedStrings 已废弃,但逻辑保留)。
- 对含中文、emoji 的字符串,底层数组仍是 char[] 或 int[],trimToSize 行为不变
- 无需手动干预编码策略,StringBuilder 自动处理


















