我有一个WinForm应用程序,它定期轮询TCP服务器并下载一些用户数据(JSON表示法)。出于某种原因,此应用程序的内存使用量随着以下方法的每次调用而增加:
private void timerElapsed(object sender, ElapsedEventArgs e)
{
if (!isPolling)
{
isPolling = true;
try
{
using (System.Net.WebClient wc = new System.Net.WebClient())
{
jsonTemp = wc.DownloadString(serverUrl);
isPolling = false;
}
}
catch (Exception ex)
{
isPolling = false;
}
}
else
{
isPolling = false;
}
}
每当调用wc.DownloadString时,我的应用程序的占用空间都会增加。
由于WebClient已经实现了IDisposable,它应该在using指令之后自动处理,或者我错了吗?
答案 0 :(得分:1)
嗯,这是可以预料的。内存使用量仅在垃圾回收后才会下降。这不是C或Pascal - 当变量超出范围或using
块结束时内存不释放 - 内存仅在内存压力下释放(.NET模型使分配非常便宜,而集合是相对昂贵的,实际上并不太依赖于你释放多少内存 - 因此,牺牲一些MiB来更快地将内存中的垃圾保存一段时间并一次释放100个对象要快得多,而不是收集一百次)。
我们在这里谈论的数字有多大? MiBs并不值得关注,只有当它平均稳定攀升(超过数十万次通话)时才应该开始寻找泄漏。另外,你在检查什么样的记忆?私人记忆?虚拟内存?通勤记忆?
如果垃圾收集在内存中有固定句柄时启动,可能会发生内存泄漏 - 这会阻止堆压缩。您可以在CLRProfiler中轻松看到这一点。但是,如果堆碎片太高,这真的很重要。
至于IDisposable
和GC,我得到了这个答案:Does the "using" keyword mean the object is disposed and GC'ed?