我编写了一个.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();
}
答案 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
的所有对象,例如WebResponse
和StreamReader
。
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.
}