C#StreamReader关闭-内存泄漏?
我编写了一个.NETC#windows服务,它在我们的服务器上运行了很长一段时间(几个月) 昨天我检查了一下,发现它使用了600MB的内存。 我重新启动了服务,现在它使用了60MB的ram 我已经开始检查它为什么会占用这么多内存。 以下功能是否会导致内存泄漏? 我认为StreamReader缺少.Close()。 作为测试,我已经在循环中运行了1000次以下函数,但没有看到内存增加C#StreamReader关闭-内存泄漏?,c#,.net,visual-studio,.net-4.0,C#,.net,Visual Studio,.net 4.0,我编写了一个.NETC#windows服务,它在我们的服务器上运行了很长一段时间(几个月) 昨天我检查了一下,发现它使用了600MB的内存。 我重新启动了服务,现在它使用了60MB的ram 我已经开始检查它为什么会占用这么多内存。 以下功能是否会导致内存泄漏? 我认为StreamReader缺少.Close()。 作为测试,我已经在循环中运行了1000次以下函数,但没有看到内存增加 private static string GetTemplate(string queryparams) {
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();
}
您的代码正在关闭响应,但没有关闭读取器
var tmp = string.Empty;
using(var reader = new StreamReader(response.GetResponseStream())
{
tmp = reader.ReadToEnd();
}
/// do whatever with tmp that you want here...
您的代码正在关闭响应,但没有关闭读取器
var tmp = string.Empty;
using(var reader = new StreamReader(response.GetResponseStream())
{
tmp = reader.ReadToEnd();
}
/// do whatever with tmp that you want here...
它可能,潜在地,取决于您使用它的频率,因为您不使用esplicit调用来处理Reader()。为了确保您在这些行中尽了最大努力,请将它们写下来,如下所示:
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.
}
它可能,潜在地,取决于您使用它的频率,因为您不使用esplicit调用来处理Reader()。为了确保您在这些行中尽了最大努力,请将它们写下来,如下所示:
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.
}
所有实现了
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();
}
所有实现了
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();
}
如果你想知道内存是否会增加,我建议你进行1000次以上的迭代。如果是内存泄漏,每次迭代只会占用一小部分内存
我不确定这是否是内存泄漏的原因,但最好在使用完StreamReader后关闭它。如果您想知道内存是否会增加,我建议使用1000多次迭代。如果是内存泄漏,每次迭代只会占用一小部分内存
我不确定这是否是内存泄漏的原因,但最好在使用完StreamReader后关闭它。使用StreamReader时,最好使用“using”,然后在对象不再在作用域中时实现IDisposable接口
using (var reader = new StreamReader(FilePath))
{
string tmp = reader.ReadToEnd();
}
至于你的问题,1000次并不是很多次的递归。试着离开应用程序几个小时,然后打上几十万个时钟,这会给你一个更好的指示。对于StreamReader,最好使用“使用”,然后在对象不再在范围内时实现IDisposable接口
using (var reader = new StreamReader(FilePath))
{
string tmp = reader.ReadToEnd();
}
至于你的问题,1000次并不是很多次的递归。试着让应用程序运行几个小时,然后计时10万次,这会给你一个更好的指示。代码不会产生内存泄漏 正如大家所指出的那样,代码并不理想(这将导致关闭资源的时间比您预期的要晚),但当GC开始运行并最终确定未使用的对象时,它们将被释放
你确定你看到了内存泄漏,还是仅仅假设你有一个基于半随机值的内存泄漏?即使未分配任何对象,CLR也可能无法释放托管堆使用的内存。如果没有足够的内存压力(特别是在x64中),GC可能不需要运行。代码不会产生内存泄漏 正如大家所指出的那样,代码并不理想(这将导致关闭资源的时间比您预期的要晚),但当GC开始运行并最终确定未使用的对象时,它们将被释放
你确定你看到了内存泄漏,还是仅仅假设你有一个基于半随机值的内存泄漏?即使未分配任何对象,CLR也可能无法释放托管堆使用的内存,如果没有足够的内存压力(特别是在x64中),GC可能不需要运行。ResponseStream和Response如何?两者都实现IDisposable,并且应该被释放。因此,您的代码缺少2条使用语句的语句。我理解我缺少对读卡器的关闭:)。最大的问题是,这会导致600mb ram的使用吗?ResponseStream和Response如何?两者都实现IDisposable,并且应该被释放。因此,您的代码缺少2条使用语句的语句。我理解我缺少对读卡器的关闭:)。最大的问题是,这会导致600mb ram的使用吗?流还实现IDisposable。@处理
StreamReader
的spender将关闭(并处理)底层流。同意。但是,通常我也会将其包括在内,以防我以后决定转移到另一个处理不是隐式的读取实现。Stream还实现IDisposable。@spender处理StreamReader
将关闭(并处理)基础流。同意。但是,通常我也会将其包括在内,以防我以后决定转移到另一个不隐含处理的读取实现。对于内存泄漏一点也不确定,我只是在任务管理器中看到了使用600mb ram(我总共只有4gb)的服务,这对我来说真的没有意义。请修复您的代码:)。要确认是否是泄漏,最好使用.Net内存探查器(搜索-大量信息),但您可以通过添加对GC的调用进行欺骗。收集足够多的数据以进行调查,并查看内存使用是否一直在增长或只是稳定在某个值。请确保您知道如何重现该条件,否则您将如何知道行为是否发生了变化。Alexei,StreamReader等是否有一些特殊之处,可以在未经处理的情况下不会导致内存泄漏?如果应用程序退出,当然,整个过程将与分配的任何资源一起终止。但是,在一个长时间运行的服务中,这可能是一个真正的问题。我遗漏了什么吗?如果没有处理,没有CLR对象泄漏内存(错误不算在内)。所有管理本机资源(如FileStream)的CLR类都具有Dispose和Finalizer,因此,如果您未能处理对象,它最终将被垃圾收集并释放非管理资源。对于纯托管对象(如大多数xxreader类),有