C# 释放对象和列表使用的内存

C# 释放对象和列表使用的内存,c#,memory,memory-management,garbage-collection,C#,Memory,Memory Management,Garbage Collection,我试图了解垃圾收集过程,我想我明白了。但是当我处理一些代码时,它并不像我预期的那样工作。 在下面的代码中,我刚刚创建了1.000.000对象并将它们添加到列表中。过了一段时间,没有什么东西了,只有内存阻塞,没有减少。如何在移除所有对象后释放内存 谢谢 private void button1_Click(object sender, EventArgs e) { List<Test> tesst = new List<Test>()

我试图了解垃圾收集过程,我想我明白了。但是当我处理一些代码时,它并不像我预期的那样工作。 在下面的代码中,我刚刚创建了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();
    }

你为什么要手动释放内存?这是有充分理由的,但我想确定你的处境需要这样做

您可以通过调用
GC.Collect()
并可选地使用一个参数告诉它要收集哪一代来强制垃圾收集。您可以阅读更多关于这方面的内容,其中包括一个与您尝试执行的测试类似的测试

如何在移除所有对象后释放内存


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

这似乎真的是一个需要重新思考流程的场景。我认为这不是手动与GC交互的工作。也许如果你在不同的问题中发布一些代码,人们可以提出一些不同的解决问题的方法?

我正在批处理代码中执行一些操作,我有内存问题。这就是我尝试手动释放内存的原因。当您尝试分配内存时,内存压力太大(即在分配更多内存之前需要释放内存),GC将为您解决这一问题。它会在分配给你更多内存之前把它清理干净。如果您遇到与内存相关的异常,那么这是一个更好的问题。在这种情况下,你应该让它做它的事情。我在批处理操作中有一些内存问题。调用析构函数但内存使用持续时间过长是否正常?@TemporaryName如果您确实存在一些内存问题,请发布一个可复制的示例,您的代码中可能存在一些内存泄漏。99.99%的时间不应该手动启动垃圾收集。此外,我也不确定你所说的“析构函数”(这不是一个非常友好的词)。假设它是终结器,您可能也不想创建它,除非您有非托管资源。是的。作为垃圾收集过程的一部分,项目准备好收集,标记为准备收集,然后最终收集。调用终结器通常发生在准备收集阶段。
    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()
    {
    }
}