为何字符串拼接函数内存占用过高?StringBuilder对比解析
字符串拼接的内存问题解析
问题背景
原代码用于将字符串列表拼接为单个逗号分隔字符串:
private string ConvertOriginalDataListToString(List<string> originalDataList) { string totalOriginalData = string.Empty; foreach (var eachOriginalData in originalDataList) { if (totalOriginalData == string.Empty) { totalOriginalData = eachOriginalData; } else { totalOriginalData = totalOriginalData + "," + eachOriginalData; } } return totalOriginalData; }
运行该函数前内存占用约60MB,运行时内存占用飙升至200MB以上。改用StringBuilder后内存问题得到解决:
private string ConvertOriginalDataListToString(List<string> originalDataList) { StringBuilder totalOriginalData = new StringBuilder(); foreach (var eachOriginalData in originalDataList) { totalOriginalData.Append(eachOriginalData); totalOriginalData.Append(","); } totalOriginalData.Remove(totalOriginalData.Length - 1, 1); return totalOriginalData.ToString(); }
问题解答
1. 原函数内存占用过高的原因
C#的string是不可变类型,每次执行+拼接时,不会修改原有字符串的内容,而是在内存中创建一个全新的字符串对象来存储拼接后的结果。
如果列表中有N个字符串,循环过程中会产生N-1个中间字符串对象。当列表规模较大时,这些临时字符串会占用大量堆内存,且旧的字符串对象需要等待垃圾回收(GC)处理,在GC触发前就会导致内存占用急剧上升。
2. string+string与StringBuilder.Append的区别
string+string拼接:- 基于不可变字符串实现,每次拼接都会生成新的字符串对象,产生大量临时垃圾。
- 内存开销随拼接次数线性增长,拼接次数越多,内存占用越高、性能越差。
- 仅适合少量、简单的字符串拼接场景。
StringBuilder.Append:StringBuilder内部维护一个可变的字符数组,Append操作直接在该数组上修改内容,仅当数组容量不足时才会扩容(扩容次数远少于拼接次数)。- 内存开销稳定,避免了大量临时对象的产生,内存占用和性能都远优于多次
string+string拼接。 - 适合循环拼接、大规模字符串拼接场景。
内容的提问来源于stack exchange,提问作者JH. Lee
相关产品推荐
相关产品推荐

