我支持一个应用程序,它使用大量的字符串连接,我相信这是内存泄漏的原因,最终会导致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的引用包含:“Hello我的名字是Joe Blogs你的名字是什么?”。我的问题是;当垃圾收集器超出范围时,所有这些字符串都被垃圾收集器拾取了吗?即当子程序完成运行时。我似乎有内存泄漏,并认为我应该真正使用StringBuilder对象。
答案 0 :(得分:3)
在您声明的情况下......您需要使用stringbuilder class并且不要连接。
垃圾收集不一定在方法块结束后但稍后发生。
有关String concatenation
和StringBuilder
之间更好的比较和解释,请参阅此链接。
Improving String Handling Performance in .NET Framework Applications
答案 1 :(得分: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