【问题标题】:Releasing The Memory Used By Objects And Lists释放对象和列表使用的内存
【发布时间】:2016-07-15 14:20:36
【问题描述】:

我正在尝试了解垃圾收集过程,我想我明白了。但是当我处理一些代码时,它并没有像我预期的那样工作。 在下面的代码中,我刚刚创建了 1.000.000 对象并将它们添加到列表中。过了一会儿,没有对象,但内存卡住并且没有减少。删除所有对象后如何释放内存?

谢谢

        private void button1_Click(object sender, EventArgs e)
    {
        List<Test> tesst = new List<Test>();

        for (long i = 0; i < 1000000; i++)
        {
            using (Test test = new Test())
            {

                test.LongObj = i;
                test.StrObj = i.ToString();
                test.DecObj = Convert.ToDecimal(i);
                tesst.Add(test);
            }
        }
        Process proc = Process.GetCurrentProcess();
        proc.Refresh();
        label1.Text = Test.counter.ToString();
        label2.Text = (proc.PrivateMemorySize64 / 1048576).ToString();
        for (int i = 0; i < tesst.Count; i++)
        {
            tesst[i] = null;
        }
        tesst.Clear();
        tesst = null;

    }

    private void button2_Click(object sender, EventArgs e)
    {
        Process proc = Process.GetCurrentProcess();
        proc.Refresh();
        label1.Text = Test.counter.ToString();
        label2.Text = (proc.PrivateMemorySize64 / 1048576).ToString();
    }

还有示例类

    public class Test : IDisposable
{
    public static long counter = 0;

    public long LongObj { get; set; }
    public string StrObj { get; set; }
    public decimal DecObj { get; set; }

    public Test()
    {
        Interlocked.Increment(ref counter);
    }

    ~Test()
    {
        Interlocked.Decrement(ref counter);
    }
    public void Dispose()
    {
    }
}

【问题讨论】:

    标签: c# memory memory-management garbage-collection


    【解决方案1】:

    您究竟为什么要尝试手动释放内存?有正当的理由,但我想确保您处于需要它的情况。

    您可以通过调用GC.Collect() 来强制进行垃圾收集,并且可以选择使用参数告诉它要收集哪一代。您可以阅读有关此here 的更多信息,其中包含与您尝试做的类似的测试。

    【讨论】:

    • 我在批处理代码中做一些操作,内存有问题。这就是我尝试手动释放内存的原因。
    • 当您尝试分配内存并且“内存压力”太大(即在分配更多内存之前需要释放内存)时,GC 会为您处理。它会在分配更多内存之前将其清理干净。如果您遇到与内存相关的异常,这是一个更好的问题。在这种情况下,你应该让它做它的事情。
    【解决方案2】:

    如何实现在所有对象删除后释放内存?

    你没有,你让 GC 完成它的工作。强制垃圾回收(使用System.GC.Collect())几乎总是一个坏主意。

    【讨论】:

    • 我的批处理操作中有一些内存问题。调用析构函数但内存使用持续时间过长是否正常?
    • @TemporaryName 如果您确实有一些内存问题,请发布一个可重现的示例,您的代码中可能有一些内存泄漏。 99.99% 的时间您不必手动启动垃圾收集。另外,我不确定您所说的“析构函数”是什么(这不是 C# 非常友好的词)。假设它是终结器,您可能也不想创建它,除非您有非托管资源。
    • 是的。作为垃圾收集过程的一部分,项目准备好收集,标记为准备好收集,然后最终收集。调用终结器通常发生在准备收集阶段。
    【解决方案3】:

    这看起来确实是您需要重新考虑流程的情况。我认为这不是手动与 GC 交互的工作。也许如果您将一些代码发布在不同的问题中,人们可能会提出一些想法以不同的方式解决问题?

    【讨论】:

      猜你喜欢
      • 2010-10-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-15
      • 1970-01-01
      • 2014-12-30
      相关资源
      最近更新 更多