0

我支持一个使用大量字符串连接的应用程序,我相信这是内存泄漏的原因,最终导致 OutOfMemory 异常。请看下面的代码:

Public Sub ConcatenateString() As String Dim Test1 As String

Test1 = "Hello" 
Test1=Test1 & "my" 
Test1=Test1 & "name" 
Test1=Test1 & "is" 
Test1=Test1 & "joe" 
Test1=Test1 & "blogs" 
Test1=Test1 & "what" 
Test1=Test1 & "is" 
Test1=Test1 & "yours?" 'line 10

return Test1

End Sub

我相信在第 10 行内存中有九个字符串,因为 String 是一个不可变对象,但只有一个对 String Test1 的引用,其中包含:“你好,我的名字是 Joe Blogs,你的名字是什么?”。我的问题是;当它们超出范围时,垃圾收集器是否会拾取所有这些字符串?即当子例程完成运行时。我似乎有内存泄漏,我认为我真的应该使用 StringBuilder 对象。

4

2 回答 2

3

在您所说的这种情况下......您需要使用stringbuilder 类并且不要进行连接。

垃圾收集不一定会在方法块结束后发生,而是在稍后的某个时间发生。

有关 和 之间的更好比较和解释,请参阅此String concatenation链接StringBuilder

提高 .NET Framework 应用程序中的字符串处理性能

字符串连接与内存分配

于 2012-06-16T15:29:50.843 回答
2

即使字符串非常大,字符串的连接也不太可能导致内存不足异常。在虚拟内存的这些日子里,内存不足异常很少表明 RAM 实际耗尽。相反,内存不足异常的常见嫌疑是您用完了系统句柄(例如 GDI 对象、文件句柄)。您可以通过在任务管理器中显示这些列来查看正在使用的句柄总数。每个进程可以创建的最大句柄取决于您拥有的 Windows 版本及其设置方式,但通常最大值为 10,000。

一旦创建的字符串不再被引用,它们就被认为是死的,垃圾收集器将销毁它们并释放内存。所以,是的,只要方法存在,所有这些字符串最终都会被收集,但不能保证它什么时候会这样做。如果你真的需要强制垃圾收集器立即收集死对象,你可以通过调用GC.Collect().

但是,像这样连接字符串是不好的做法。这是非常低效的,尤其是对于大字符串。在这种情况下,您应该使用 StringBuilder:

Public Sub ConcatenateString() As String Dim Test1 As String
    Dim builder As New StringBuilder()
    builder.Append("Hello")
    builder.Append("my")
    builder.Append("name") 
    builder.Append("is")
    builder.Append("joe") 
    builder.Append("blogs") 
    builder.Append("what")
    builder.Append("is")
    builder.Append("yours?")
    Return builder.ToString()
End Sub
于 2012-06-16T15:34:03.873 回答