C#StreamReader关闭 - 内存泄漏?

时间:2012-05-10 15:52:50

标签: c# .net visual-studio .net-4.0

我编写了一个.NET C#windows服务,它在我们的服务器上运行了很长时间(几个月)。

昨天我查了一下,发现它使用了600MB的内存。 我重新启动了该服务,现在它使用60MB内存。

我已经开始检查它为什么要使用这么多内存了。 以下功能是否会导致内存泄漏?

我认为它缺少StreamReader的.Close()。

作为测试,我在循环中运行以下函数1000次,我没有看到内存上升。

private static string GetTemplate(string queryparams)
{
    WebRequest request = HttpWebRequest.Create(uri);
    request.Method = WebRequestMethods.Http.Get;
    WebResponse response = request.GetResponse();
    StreamReader reader = new StreamReader(response.GetResponseStream());
    string tmp = reader.ReadToEnd();
    response.Close();
}

6 个答案:

答案 0 :(得分:4)

您的代码正在关闭响应,但不是读者。

var tmp = string.Empty;

using(var reader = new StreamReader(response.GetResponseStream())
{
    tmp = reader.ReadToEnd();  
}

/// do whatever with tmp that you want here...

答案 1 :(得分:4)

应该处理实施IDisposable的所有对象,例如WebResponseStreamReader

private static string GetTemplate(string queryparams)
{
    WebRequest request = HttpWebRequest.Create(uri);
    request.Method = WebRequestMethods.Http.Get;
    using(var response = request.GetResponse())
    using(var reader = new StreamReader(response.GetResponseStream())
       string tmp = reader.ReadToEnd();
}

答案 2 :(得分:3)

代码不会产生内存泄漏。

代码并不理想,因为每个人都指出(会导致关闭资源的时间超出预期),但是当GC开始运行并完成未使用的对象时,它们将被释放。

你确定你看到了内存泄漏,或者你只是假设你有一个基于某些半随机值的内存?即使没有分配任何对象,CLR也可能不释放托管堆使用的内存,如果没有足够的内存压力,GC可能不需要运行(特别是在x64中)。

答案 3 :(得分:2)

如果您想查看内存是否会增加,我会建议超过1000次迭代。如果是你的内存泄漏,每次迭代只会占用一小部分内存。

我不确定这是否是您的内存泄漏的来源,但是当您完成它们时,.Close()您的StreamReader的良好做法。

答案 4 :(得分:1)

使用StreamReader时,最好使用'using',然后当对象不再在范围内时实现IDisposable接口。

using (var reader = new StreamReader(FilePath))
  {
    string tmp = reader.ReadToEnd();
  }

至于你的问题,1000次递归并不是很多。尝试离开应用程序几个小时,然后计算几十万,这将为您提供更好的指示。

答案 5 :(得分:0)

它可能会取决于您使用它的频率,因为您不使用对Dispose()的esplicit调用。为了确保你在这些行中尽你所能,把它们写下来:

private static string GetTemplate(string queryparams)
{
    WebRequest request = HttpWebRequest.Create(uri);
    request.Method = WebRequestMethods.Http.Get;
    WebResponse response = request.GetResponse();

    using(StreamReader reader = new StreamReader(response.GetResponseStream())){

         string tmp = reader.ReadToEnd();
         response.Close();
    }

    // here will be called Dispose() of the reader 
    // automatically whenever there is an exception or not.
}