在显式调用 GC 之前,应用程序不会释放内存

发布于 2025-01-01 16:58:05 字数 833 浏览 1 评论 0原文

我同时启动许多线程,每个线程将数据写入队列或从队列中读取数据;数据在处理并存储到数据库时逐渐出队。由于某种原因内存没有释放,尽管队列是空的,并且我确保数据读取器和数据处理器之间的所有事件订阅在线程结束时取消订阅。的数量squatted RAM恰好是由二进制读取器读取并放入队列的数据量。

为了隔离问题,我绕过了处理和数据库存储步骤。
为什么在所有线程完成后,RAM 仍然占用很长时间,直到我显式调用 GC.Collect() 或终止程序?我在队列清空后手动将其作废,同时也将读取数据的Binary Reader作废。我认为这足以让 GC 至少在几分钟后醒来并进行内务处理。

在此处输入图像描述

编辑: (删除后重新表述)问题: 简而言之,我总是被告知默认的 GC 行为可以正确管理内存,并且我几乎永远不会显式调用 GC 并让框架来完成这项工作。
我想知道为什么在这种情况下,仅当显式调用 GC.Collect 时,内存使用率才会下降

编辑:
没有 GC Collect

在此处输入图像描述

使用 GC Collect(定期调用) 在此处输入图像描述

I am launching many threads simultaneously, each one writing / reading data into/from a queue; Data is dequeued progressively while it is processed and stored to DB. For some reason the memory is not freed although the Queues are empty and I made sure all event subscription between the data reader and the data processor are unsubscribed at the end of the threads.The amount of squatted RAM is Exactly the amount of the data that is read by binary readers and put into queues.

In order to isolate the problem, I have bypassed the Processing and the DB Storing step.

Why would be the RAM still squatted long after all threads are finished, until I explicitly call GC.Collect() or terminate the program? I manually nullified the Queue after it is emptied, and also nullified the Binary Reader that read the data. I thought that would be enough for the GC to wake up and do its housekeeping at least after a few minutes.

enter image description here

EDIT :
The (reformulated after deletion) QUESTION :
In short, I was always told that the default GC behaviour managed the memory properly and that I shall almost never call the GC explicitly and let the framework do the job.
I would like to know why in this case memory usage drops down only when an explicit Call is made to GC.Collect

EDIT :
Without GC Collect

enter image description here

With GC Collect (Called on a regular basis)
enter image description here

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

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

发布评论

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

评论(3

逆流 2025-01-08 16:58:05

在三种情况下可能会发生垃圾收集(请参阅 MSDN ):

1.) 系统物理内存不足。

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

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

从您的描述看来,框架决定既不是 1.) 也不是 2.) 的情况,因此它只会在您调用 GC.Collect() 时收集。

There are three conditions when a Garbage collection might occur (see MSDN):

1.) The system has low physical memory.

2.) 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.

3.) 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.

From your description it sounds like the framework decided neither 1.) nor 2.) are the case hence it will only collect when you call GC.Collect()

许仙没带伞 2025-01-08 16:58:05

根据屏幕截图,在应用程序的整个运行过程中,您的内存使用量似乎从未超过 50%。对于 .NET 框架来说,保留该内存比停止应用程序(或至少占用大量 CPU 时间来检查活动性)来收集垃圾要快得多。如果您将机器的 RAM 削减到 2 GB 左右,我确信垃圾收集器会加强并将内存使用量保持在硬件限制内。

Based on the screenshot, it appears that your memory usage never goes over 50% during the entire run of the application. It's much faster for the .NET framework to leave that memory alone than to stop your application (or at least take up a lot of CPU time in checking for liveness) in order to collect the garbage. If you cut your machine's RAM to 2 GB or so, I'm sure that the garbage collector would step up and keep memory usage within the hardware limits.

秋心╮凉 2025-01-08 16:58:05

看来您正在泄漏对象,您应该使用 Windbg 创建转储,然后使用 sos.dll 来跟踪对象的根。

您可以按照此关于如何跟踪对象的“根”并查看导致这些泄漏的原因的说明

It seems you are leaking objects you should use windbg to create a dump then use sos.dll to track root for your objects.

You can follow this explanation on how to track "roots" for your objects and see what is causing these leaks.

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