setLength(0)能减少GC是因为仅将count置0,复用底层数组,避免重复分配对象和char[]内存。正确做法:循环外初始化并预设容量,每次循环前setLength(0),再append;切忌混用delete或new,toString后须立即setLength(0)。

直接调用 StringBuilder.setLength(0) 是复用缓冲区内存、避免频繁创建新对象、降低 GC 压力的常用技巧,但要注意它只清空逻辑长度,不释放底层 char 数组,也不重置容量。
为什么 setLength(0) 能减少 GC?
setLength(0) 仅将内部 count 字段设为 0,表示当前“有效字符数”为 0;底层的 char[] value 数组仍保留,且容量(capacity)不变。相比每次循环都 new StringBuilder(),它省去了对象分配和后续数组内存分配的开销,尤其在高频循环中效果明显。
正确复用的写法示例
以下是在循环中安全复用的典型模式:
- 在循环外初始化一次
StringBuilder,预估合理初始容量(如new StringBuilder(128)) - 每次循环开始前调用
sb.setLength(0),清空内容但保留底层数组 - 接着用
append()写入新内容,无需担心扩容——只要新内容长度 ≤ 当前 capacity,就不会新建数组 - 若某次内容超长导致自动扩容,底层数组会被替换,但这是按需发生,比每次都新建更可控
容易踩的坑
不要混用 delete(0, sb.length()) 或 sb = new StringBuilder() ——前者语义等价但略慢(多一次范围检查),后者完全失去复用意义;也不要依赖 toString() 后继续复用而不调用 setLength(0),因为 toString() 返回的是新字符串,不影响 StringBuilder 状态,但若忘记清空,下次 append() 会在旧内容后追加。
配合 toString() 使用的注意事项
每次生成字符串后,应立刻 setLength(0),而不是等下次循环再清理。例如:
- ✅ 正确:
String s = sb.toString(); sb.setLength(0); - ❌ 危险:
String s = sb.toString(); // 忘记清空 → 下次 append 会拼在旧结果后面
如果需要返回字符串并确保 builder 干净,可封装成小工具方法,避免遗漏。

















