一、方法定义
public void trimToSize()
参数:
- 无参数
返回值:
void
(无返回值)
二、功能说明
trimToSize()
方法用于将 StringBuilder
的内部缓冲区容量(capacity)调整为当前字符序列的实际长度(length),以节省内存空间。
核心功能:
- 减少内存占用:释放未使用的缓冲区空间
- 优化存储:使容量等于当前字符串长度
- 不可逆操作:调用后若再追加内容,可能触发扩容
与 ensureCapacity()
的关系:
ensureCapacity(int minimumCapacity)
:确保容量至少为指定值(可能扩容)trimToSize()
:缩小容量至实际长度(只可能缩容)
三、示例代码
1. 基本使用
StringBuilder sb = new StringBuilder(100); // 初始容量100
sb.append("Hello");
System.out.println("Length: " + sb.length()); // 输出: 5
System.out.println("Capacity: " + sb.capacity()); // 输出: 100
sb.trimToSize();
System.out.println("After trimToSize:");
System.out.println("Length: " + sb.length()); // 输出: 5
System.out.println("Capacity: " + sb.capacity()); // 输出: 5
2. 验证内存优化效果
StringBuilder sb = new StringBuilder();
sb.append("A".repeat(1000)); // 添加1000个字符
System.out.println("初始 - 长度: " + sb.length() + ", 容量: " + sb.capacity());
// 示例输出: 初始 - 长度: 1000, 容量: 1024
sb.setLength(10); // 将内容截短到10个字符
System.out.println("截短后 - 长度: " + sb.length() + ", 容量: " + sb.capacity());
// 输出: 截短后 - 长度: 10, 容量: 1024 (内存仍被占用)
sb.trimToSize();
System.out.println("trimToSize后 - 长度: " + sb.length() + ", 容量: " + sb.capacity());
// 输出: trimToSize后 - 长度: 10, 容量: 10 (内存已释放)
3. 链式调用限制
StringBuilder sb = new StringBuilder("Test");
// sb.trimToSize().append("More"); // ❌ 编译错误!trimToSize() 返回 void
// 正确做法:分步调用
sb.trimToSize();
sb.append("More");
四、使用技巧
1. 在构建完成后调用
当确定不再追加内容时,调用 trimToSize()
优化内存。
StringBuilder sb = new StringBuilder();
// ... 构建字符串
sb.append("Final content");
// 构建完成,优化内存
sb.trimToSize();
// 后续只读操作或转换为String
String result = sb.toString();
2. 与 toString()
配合使用
虽然 toString()
会创建新字符串,但调用 trimToSize()
可减少 StringBuilder
自身的内存占用。
StringBuilder sb = new LargeStringBuilder();
// ... 处理
sb.trimToSize(); // 优化StringBuilder自身内存
String result = sb.toString(); // 创建String对象
3. 监控内存使用
可用于调试和性能分析。
System.out.println("Before: len=" + sb.length() + ", cap=" + sb.capacity());
sb.trimToSize();
System.out.println("After: len=" + sb.length() + ", cap=" + sb.capacity());
五、常见错误
1. 误以为返回 StringBuilder
// ❌ 错误:尝试链式调用
// StringBuilder result = sb.trimToSize().append("text"); // 编译错误
// ✅ 正确:分步调用
sb.trimToSize();
sb.append("text");
2. 在频繁修改前调用
StringBuilder sb = new StringBuilder();
sb.trimToSize(); // 此时容量=0
sb.append("Hello"); // 触发扩容
sb.append(" World"); // 可能再次扩容
// 失去了 StringBuilder 预分配容量的优势
3. 期望释放 String 内存
trimToSize()
只优化 StringBuilder
自身的缓冲区,不影响通过 toString()
创建的 String
对象。
六、注意事项
- 无返回值:
trimToSize()
返回void
,不支持链式调用。 - 仅缩容:只能减少容量,不能增加。
- 性能权衡:
- 优点:节省内存
- 缺点:后续追加内容可能触发数组复制(扩容)
- 线程不安全:与其他
StringBuilder
方法一样,非线程安全。 - JVM 优化:现代 JVM 内存管理高效,小幅度缩容可能意义不大。
- 实际长度:基于
length()
调整容量,而非字符内容大小。
七、最佳实践与性能优化
✅ 最佳实践
场景 | 推荐做法 |
---|---|
构建完成后的优化 | 在确定不再修改后调用 trimToSize() |
内存敏感应用 | 对大型 StringBuilder 调用以减少内存占用 |
工具类/库开发 | 提供选项是否调用 trimToSize() |
高频操作 | 避免频繁调用,通常不需要 |
⚠️ 性能建议
- 一般应用:通常不需要显式调用
trimToSize()
,JVM 和StringBuilder
的默认扩容策略已足够高效。 - 内存敏感场景:如处理大量文本、Android 应用、嵌入式系统,可在构建完成后调用。
- 避免过度优化:微小的内存节省可能带来后续扩容的性能开销。
示例:何时调用
// ✅ 推荐:构建完成,长期持有
StringBuilder config = new StringBuilder();
// 构建配置字符串
config.trimToSize(); // 优化内存,长期使用
// ⚠️ 不推荐:频繁修改
StringBuilder log = new StringBuilder();
while (hasMoreLogs()) {
log.trimToSize(); // ❌ 每次都缩容,后续append会扩容,性能更差
log.append(nextLog());
}
八、总结
StringBuilder.trimToSize()
是一个内存优化工具,用于将内部缓冲区缩减到实际需要的大小。
核心要点:
项目 | 说明 |
---|---|
功能 | 缩小容量至当前长度 |
返回值 | void ,不支持链式调用 |
主要用途 | 节省内存空间 |
调用时机 | 构建完成且不再修改时 |
性能影响 | 节省内存,但可能增加后续扩容开销 |
必要性 | 一般应用中非必需 |
使用口诀:
trimToSize缩容量,内存优化有一套;
返回void莫链式,构建完成才需要;
频繁修改别乱用,扩容代价要知道;
一般情况可不用,省心省力最重要。
在绝大多数情况下,可以安全地忽略 trimToSize()
。只有在处理超大字符串或内存极度敏感的场景下,才需要考虑使用它来优化内存占用。