为什么这个对象没有被垃圾回收

发布于 2025-01-07 11:15:04 字数 598 浏览 0 评论 0原文

在下面的代码段中,我想知道为什么在函数调用后没有收集 testvectors 。我看到内存使用量上升到 270Mb,然后永远保持在这个水平。

该函数直接从 Main 调用。

private static void increaseMemoryUsage()
{
    List<List<float>> testvectors = new List<List<float>>();
    int vectorNum = 250 * 250;
    Random rand = new Random();

    for (int i = 0; i < vectorNum; i++)
    {
        List<Single> vec = new List<Single>();

        for (int j = 0; j < 1000; j++)
                {
            vec.Add((Single)rand.NextDouble());
        }
        testvectors.Add(vec);
    }
}

In the following code segment, I am wondering why testvectors is not collected after the function call. I see memory usage go up to 270Mb and then stay there forever.

This function is directly called from Main.

private static void increaseMemoryUsage()
{
    List<List<float>> testvectors = new List<List<float>>();
    int vectorNum = 250 * 250;
    Random rand = new Random();

    for (int i = 0; i < vectorNum; i++)
    {
        List<Single> vec = new List<Single>();

        for (int j = 0; j < 1000; j++)
                {
            vec.Add((Single)rand.NextDouble());
        }
        testvectors.Add(vec);
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

乜一 2025-01-14 11:15:04

不要将垃圾收集与引用计数混淆。当运行时决定时,内存会被释放,而不总是在不再被引用时释放。引用:

当出现以下情况之一时,就会发生垃圾收集
正确:

系统物理内存不足。

托管堆上分配的对象使用的内存
超过可接受的阈值。这意味着阈值
托管堆上的内存使用量已超出可接受的范围。这
阈值随着进程的运行而不断调整。

调用 GC.Collect 方法。几乎在所有情况下,您都没有
调用此方法,因为垃圾收集器持续运行。
此方法主要用于特殊情况和测试。

如果您有兴趣,请阅读此内容:

http://msdn.microsoft.com/en-us/library/ 0xy59wtx.aspx

Don't confuse garbage collection with reference counting. The memory is freed when the runtime decides, not always when it's no longer referenced. To quote:

Garbage collection occurs when one of the following conditions is
true:

The system has low physical memory.

The memory that is used by allocated objects on the managed heap
surpasses an acceptable threshold. This means that a threshold of
acceptable memory usage has been exceeded on the managed heap. This
threshold is continuously adjusted as the process runs.

The GC.Collect method is called. In almost all cases, you do not have
to call this method, because the garbage collector runs continuously.
This method is primarily used for unique situations and testing.

Read this if you're interested:

http://msdn.microsoft.com/en-us/library/0xy59wtx.aspx

⊕婉儿 2025-01-14 11:15:04

GC 可以在需要时运行。那可能要晚得多了。在最后一个引用消失后,没有义务立即释放一些内存。您的阵列将在下一个 Gen2 收集中收集。

除非您继续分配内存,否则函数返回后它可能永远不会运行。

您可以使用 GC.Collect() 手动触发 GC,但通常不鼓励这样做。

The GC can run when it wants. And that can be much later. There is no obligation to free some memory directly after the last reference goes away. Your array will get collected on the next Gen2 collection.

Unless you keep allocating memory, it will likely never run after the function returns.

You can manually trigger a GC with GC.Collect(), but that's generally discouraged.

帅冕 2025-01-14 11:15:04

当我运行这个时,我观察到相反的情况:

 class Program
    {
        static void Main(string[] args)
        {
            increaseMemoryUsage();

            Console.WriteLine("Hit enter to force GC");
            Console.ReadLine();

            GC.Collect();

            Console.ReadLine();
        }

        private static void increaseMemoryUsage()
        {
            var testvectors = new List<List<float>>();
            const int vectorNum = 250 * 250;
            var rand = new Random();

            for (var i = 0; i < vectorNum; i++)
            {
                var vec = new List<Single>();

                for (var j = 0; j < 1000; j++)
                    vec.Add((Single)rand.NextDouble());

                testvectors.Add(vec);
            }
        }    
    }

I observe the opposite when I run this:

 class Program
    {
        static void Main(string[] args)
        {
            increaseMemoryUsage();

            Console.WriteLine("Hit enter to force GC");
            Console.ReadLine();

            GC.Collect();

            Console.ReadLine();
        }

        private static void increaseMemoryUsage()
        {
            var testvectors = new List<List<float>>();
            const int vectorNum = 250 * 250;
            var rand = new Random();

            for (var i = 0; i < vectorNum; i++)
            {
                var vec = new List<Single>();

                for (var j = 0; j < 1000; j++)
                    vec.Add((Single)rand.NextDouble());

                testvectors.Add(vec);
            }
        }    
    }
亽野灬性zι浪 2025-01-14 11:15:04

最有可能的是,您的测试向量被提升到大型对象堆 (LOH),然后在 Gen0 收集期间不会被收集。

很好的链接此处

Most likely, your testvectors is getting promoted to the Large Object Heap (LOH) and then it is not collected during the Gen0 collection.

Good link here.

溇涏 2025-01-14 11:15:04

垃圾收集是不确定的。由 GC 决定何时是执行此操作的最佳时机。

Garbage collection is non-deterministic. It's up to GC to decide when is a good moment to do it.

情定在深秋 2025-01-14 11:15:04

尝试添加 GC。 GetTotalMemory(true) 之前和之后的increaseMemoryUsage() 方法使用情况并比较数字。

Try to add GC.GetTotalMemory(true) before and after increaseMemoryUsage() method usage and compare numbers.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文