C#GC.Collect()和Memory

时间:2014-09-09 17:59:53

标签: c# garbage-collection

我收到一个非常大的列表作为方法参数,并希望在使用后将其从内存中删除。通常我会让GC做它的事情,但我需要非常小心这个应用程序中的内存使用。

这段代码会实现我的目标吗?我已经阅读了很多不同意见并且很困惑。

public void Save(IList<Employee> employees)
    {
        // I've mapped the passed-in list
        var data = Mapper<Employee, EmployeeDTO>.MapList(employees);

        // ?????????????
        employees = null;
        GC.Collect();

        // Continues to process very long running methods....
        // I don't want this large list to stay in memory

   }

也许我应该使用另一种我不知道的技术?

2 个答案:

答案 0 :(得分:7)

如果列表不再使用,当可用内存出现问题时,GC会自动收集

但是,如果调用者在将其传递给您的函数后使用该列表,那么即使您将其设置为null,GC 也不会收集它你有一个对列表的引用 - 你不能对其他持有引用的对象做任何事情。

除非你有可衡量的问题,否则不要试图超越GC。

答案 1 :(得分:1)

这不是问题的直接答案,而是一些想法如何处理海报(@Big Daddy)提到的低内存情况。

如果您在具有8 GB内存的x64平台上遇到内存不足的情况,则应确定您的应用程序是否对其负责。如果是,则运行内存分析器(CLR Profiler或其他东西,甚至获得完整的用户转储并在其上运行WinDbg)以查看分配内存的内容。您可能有一些不再使用但仍在某处被引用的对象 - 这不是真正的内存泄漏,但它的内存在您的应用程序中没有释放 - 最体面的分析器将识别大对象(或具有大量实例的对象)及其类型。

我发现很难相信传递给这个Save函数的列表会给服务器带来8 GB的内存压力,但是我们不知道这个进程可用的可用内存量是多少它是一个进程(IIS,桌面等)

如果在具有大量输入的多个线程上调用Save,它可能会导致内存压力,但即便如此,它也不太可能,我会检查各种计数器和配置文件数据看看内存压力发生的时间和原因。