大文件合并应避免用单个StringBuilder拼接整串,而要分块构建、及时丢弃引用、流式输出。每块用小容量StringBuilder(如8192),完成后转String并回收;结果存List<String>,最后String.join合并;目标为文件或响应时直接流式write,内存恒定在KB级。

大文件合并时不用 StringBuilder 拼出完整字符串——它不是为“存整份”设计的,而是为“可控构建”服务的。真正高效的做法是分段处理、流式输出、按需合并,把内存峰值压到 KB 级别。
分块构建 + 及时丢弃引用
不要用一个 StringBuilder 读完全部内容再拼。按自然单位(如每 500 行、每个 JSON 对象、每个 XML 节点)独立构建:
- 每次新建小容量 StringBuilder,例如 new StringBuilder(8192),只负责当前块
- 构建完成立刻调用 toString() 得到不可变 String,原 StringBuilder 实例即可被 GC 回收
- 避免把 StringBuilder 本身放进 List 或长期持有——只存 String
结果暂存用 List,最后统一合并
各块拼好后存入 List<String>,而不是持续往一个 StringBuilder 里 append:
- 每个 String 底层 char[] 大小精准,无冗余容量
- 最终用 String.join("", list) 合并(JDK 8+),JVM 内部已优化
- 若必须用 StringBuilder 合并,先遍历 list 累加所有 length,再 new 一个精确容量的实例
优先流式写入,绕过内存拼接
如果目标是生成新文件或发送 HTTP 响应,根本不需要拼成一大串:
立即学习“Java免费学习笔记(深入)”;
- 用 BufferedWriter 或 OutputStreamWriter 直接 write 每个 String 块
- 分隔符(如换行、逗号)也单独 write,不累积在内存中
- 配合 try-with-resources 自动 flush 和 close,内存占用恒定且极低
注意 substring 和 toString 的隐式开销
对超大块调用 substring 或 toString 需谨慎:
- StringBuilder.toString() 会复制整个 char[],但这是必要开销;只要不长期持有 StringBuilder 引用就安全
- 避免对巨型 StringBuilder 调用 substring(0, n) 后保留返回值——旧版 JDK 可能仍引用原始大数组
- 如需截取,先 toString() 得到独立 String,再对其 substring


















