【发布时间】:2011-05-21 07:57:02
【问题描述】:
我有一个 .Net Framework #4.0 应用程序,它使用 WebRequest/WebResponse 类发出大量 Web 请求,因为我看到它存在内存泄漏(或者我做错了什么) 我写了一些简单的小应用程序来证明这一点:
class Program
{
public static void Main(string[] args)
{
while(true)
{
var webRequest = (HttpWebRequest)WebRequest.Create("http://www.gooogle.com");
Init(webRequest);
using (var webResponse = (HttpWebResponse)webRequest.GetResponse())
{
var responseStream = webResponse.GetResponseStream();
responseStream.ReadTimeout = 30;
var streamReader = new StreamReader(responseStream, Encoding.UTF8);
var page = streamReader.ReadToEnd();
streamReader.Close();
streamReader.Dispose();
responseStream.Close();
responseStream.Dispose();
webResponse.Close();
Console.WriteLine("Done");
//GC.Collect();
}
}
}
private static void Init (HttpWebRequest webRequest)
{
webRequest.Method = "GET";
webRequest.Host = "www.gooogle.com";
webRequest.UserAgent =
"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; GTB6.5; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; OfficeLiveConnector.1.4; OfficeLivePatch.1.3; .NET4.0C; .NET4.0E; InfoPath.3) chromeframe/5.0.375.62";
webRequest.Accept =
"application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*";
webRequest.KeepAlive = true;
}
}
我想出的唯一一个解决方案是使用 GC.Collect()(在示例中未标记),所有对象都已释放,所有流都已关闭,我是否遗漏了什么?
我发现了一些东西,但我不明白原因,如果我将控制台最小化,内存使用量会减少并且看起来还可以,这可能是什么原因,Conosole 或 WinForm 有问题,我该如何解决?
【问题讨论】:
-
你怎么看它有内存泄漏?
-
Stream 和 StreamReader 也实现了 IDisposable。
-
如果 GC.Collect() 修复了您的泄漏,这并不是真正的泄漏。如果不需要释放资源,GC 会挂在资源上是完全正常的。长时间运行应用程序时,您是否看到性能影响?由于内存使用量增加,是否有任何事情没有按预期执行?您是否长期分析内存使用情况?
-
删除
while(true)将是一个良好的开始 w.r.t 内存管理。 -
如果您还调用 Dispose,则不需要调用 Close,但您应该将响应流和 StreamReader 放入
using语句中。