2012-06-16 68 views
0

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

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作为字符串是不可变对象,但只有一个参考字符串的Test1包含:“你好,我的名字是乔博客你的是什么?“。我的问题是;是垃圾收集器在超出范围时拾取的所有这些字符串?即当子程序结束运行时。我似乎有一个内存泄漏,并认为我真的应该使用StringBuilder对象。

+0

弦数不能足以导致内存异常,除了没有交换的系统上或RAM离开,或用约1MB RAM的系统。 – Linuxios

+0

@ Linux_iOS.rb.cpp.c.lisp.m.sh,我支持的系统连接非常大的字符串。这是一个非常简单的例子。 – w0051977

+2

@ w0051977,在这种情况下,你已经说过......你需要使用'stringbuilder class'并且不要连接。 – Rahul

回答

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 
+0

谢谢,对文件句柄的建议+1。有没有一个有用的免费工具,你可以建议寻找内存泄漏。目前我正在使用windbg,但学习曲线似乎很陡峭。 – w0051977

+0

@ w0051977对不起,但我不熟悉任何。正如我所说的,使用跟踪句柄,您可以在逐步执行代码时看到当前任务管理器的数量增加,因此可以非常容易地确定这些泄漏来自哪里(如果存在),而没有第三方工具。 –