.net – 使用Insert()和Clear()时StringBuilder中的内存泄漏
我需要在StringBuilder中添加一些行,其中最后添加的行应该在字符串的开头,最后的最后一行.我添加一个这样的新行:
stringBuilder.Insert(0,"Some text." + Environment.NewLine); 完成后,我像这样清空StringBuilder: stringBuilder.Clear(); 我多次重复使用相同的StringBuilder,这会导致内存不足异常. 我用下面的测试程序调查了这个问题,它表明当使用Append()和Clear()时,StringBuilder的容量保持不变,无论使用多少次.但是当使用Insert()和Clear()时,StringBuilder的容量会不断增长.以下是测试结果: stringbuilder.Capacity Iteration Append Insert 0: 81984,78016 1: 81984,155938 2: 81984,233860 3: 81984,311782 4: 81984,389704 5: 81984,467626 6: 81984,545548 7: 81984,623470 8: 81984,701392 这些测试数据来自下面的测试程序.可以看出,无论有多少次执行Append()和Clear(),容量都不会改变.但是在使用Insert()和Clear()时它确实在不断增长. 问题:使用Insert()和Clear()时StringBuilder是否存在内存泄漏是否正确,因为容量不断增长,最终会导致Out of Memory异常? 要自己测试它,只需增加outerIndex的上限即可获得异常. 如果这确实应该被视为内存泄漏,我该如何向Microsoft报告? using System; using System.Text; namespace TestStringBuilder { class Program { static void Main(string[] args) { StringBuilder stringBuilderAppend = new StringBuilder(); StringBuilder stringBuilderInsert = new StringBuilder(); string capacityGrow = ""; for (int outerIndex = 0; outerIndex < 9; outerIndex++) { for (int innerIndex = 0; innerIndex < 1000; innerIndex++) { stringBuilderAppend.Append("Just some text to fill stringbuffer with 01234567890qwertyuiopasdfghjklzxcvbnm"); stringBuilderInsert.Insert(0,"Just some text to fill stringbuffer with 01234567890qwertyuiopasdfghjklzxcvbnm"); } stringBuilderAppend.Clear(); stringBuilderInsert.Clear(); capacityGrow += outerIndex + ": " + stringBuilderAppend.Capacity + "," + stringBuilderInsert.Capacity + Environment.NewLine; } //check in the debugger capacityGrow to see the capacity used in each iteration System.Diagnostics.Debugger.Break(); } } } EDIT1: stringBuilder.Clear(); stringBuilder.Capacity = 0; 这可以防止内存泄漏,并在重复使用Insert()时导致Out of Memory异常,但它也无法重用StringBuilder,这是为了防止内存的分配和释放以实现更高的速度.而不是设置Capacity = 0,也可以使用新的StringBuilder而不是Clear(). 似乎Insert()没有重用已经分配给StringBuilder的未使用的内存,但是不管添加Clear(),都会不断添加新的内存.我仍然觉得这是一个错误,因为尽管清除了StringBuilder,谁会期望内存耗尽?如果这是一个错误并且应该向Microsoft报告,我将不胜感激. EDIT2: 请关注链接并提出错误信息,否则我担心微软不会调查它:-( 结束语: >从之前的帖子中我发现了一个经验,评论者很快就说我的程序存在问题.他们非常粗鲁地评论,即使是他们错了. 解决方法我会说这种行为是可以预期的:Clear() 该文件指出:
所以Clear()删除内容但保留内存分配. Insert() 在这里,文档指出先前的内容已经转移,并且根据需要调整容量. (doc)这不完全清楚,但我假设分配了新的内存容量新长度,其余的被复制.现在.这可能不是最佳解决方案,但我认为这是它的实现方式.因此,可以预期内存不足的情况. 另一个建议:始终插入第一个位置 – 无论实施 – 都非常昂贵.如果只需要一次考虑结果,请考虑使用List< string>在第0位插入新行,然后在列表上迭代一次并构建字符串. 编辑: 在查看(假设)source之后,我认为StringBuilder确实为每个插入分配了一个新实例作为’chunk’ – 无论其他任何romm可用.我跟着调用了MakeRoom,在第2044行分配了一个新的块. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |