WebClient.DownloadString()的内存泄漏/分配问题?

时间:2014-04-29 11:29:56

标签: c# webclient

我有一个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指令之后自动处理,或者我错了吗?

1 个答案:

答案 0 :(得分:1)

嗯,这是可以预料的。内存使用量仅在垃圾回收后才会下降。这不是C或Pascal - 当变量超出范围或using块结束时内存不释放 - 内存仅在内存压力下释放(.NET模型使分配非常便宜,而集合是相对昂贵的,实际上并不太依赖于你释放多少内存 - 因此,牺牲一些MiB来更快地将内存中的垃圾保存一段时间并一次释放100个对象要快得多,而不是收集一百次)。

我们在这里谈论的数字有多大? MiBs并不值得关注,只有当它平均稳定攀升(超过数十万次通话)时才应该开始寻找泄漏。另外,你在检查什么样的记忆?私人记忆?虚拟内存?通勤记忆?

如果垃圾收集在内存中有固定句柄时启动,可能会发生内存泄漏 - 这会阻止堆压缩。您可以在CLRProfiler中轻松看到这一点。但是,如果堆碎片太高,这真的很重要。

至于IDisposable和GC,我得到了这个答案:Does the "using" keyword mean the object is disposed and GC'ed?