在.NET中,当你最小化程序时,垃圾回收器会被调用吗?

我用C#创build了一个程序。 该程序使用了大约60-70 MB的记忆。 但是,当我最小化这个程序时,它需要更less的内存,也就是只有10 MB。

当我最大化或回到该程序时,它使用了20 MB …

为什么会这样呢?

当你最小化程序时,垃圾收集器是否被调用?

这与垃圾回收没有任何关系 – 这种情况也发生在非.NET程序上(尽量减少浏览器,同时查看内存占用情况)。

当你最小化一个程序的时候,windows操作系统将不再需要保持UI组件在内存中,因此内存要求较低。

也就是说 – 当应用程序被最小化时,windows会修剪工作集。

看到这个 channel9线程和这个知识库文章 (谢谢@Sasha Goldshtein )。

垃圾收集器每当它决定运行时就运行; 这不一定与用户所做的任何事情相关联,当然也不会将应用程序最小化。 通常,您可以将其视为与可用内存总量相比内存使用量的函数。 但重要的是,作为程序员,这对你来说应该是有点不透明的。 垃圾收集与手动内存管理相比,最大的好处就是你不用担心这些。

我怀疑你的问题,你正在使用Windows任务管理器来监视你的应用程序的内存使用情况,并确定何时发生垃圾回收。 这是一个巨大的错误。 如果你真的需要做记忆分析,你需要投资一个合适的分析器。 任务管理器不是为此设计的,而且你经常会得到错误的读取。

更具体地说,当您将应用程序最小化时,看起来应用程序占用的内存量明显减少的原因只是尝试使用“任务管理器”执行内存分析时出现的错误读取之一。 实际上,每当你最小化一个应用程序时,Windows内核就会自动地分出它所使用的大部分内存。 你会看到所有的应用程序,而不仅仅是用.NET编写的。 由于任务管理器正在向您显示当前存在于实际内存中的应用程序正在使用的总内存的子集(即未被分页到磁盘的量),因此,看起来内存使用情况已经降低它并不是真的。 为了获得更准确的阅读,您应该查看进程的“Private Bytes”值。 这篇知识库文章提供了更多的细节。

这篇文章解释了所有: 记忆神秘

这是来自上述网站的摘录:

.Net城市传奇

加载后立即最小化并最大化应用程序,可以减少.Net Windows Forms应用程序的工作集大小。 Windows操作系统在最小化时修剪应用程序的工作集。 在加载前面提到的所有程序集时,简单使用的内存被最小化和最大化应用程序的过程所削减。 您可以通过仅使用Form1创建和运行Windows窗体应用程序并且不添加代码来演示此行为。

  1. 创建并运行简单的应用程序。

  2. 打开Windows任务管理器,然后打开它的进程选项卡。 你会看到任务管理器显示你的应用程序的内存使用量约。 12.5 MB。

  3. 现在最小化你的应用程序,然后最大化 再次检查任务管理器。 你会看到任务管理器现在显示你的应用程序的内存使用量约。 1.5 MB。 在应用程序启动时用于加载程序集的内存在最小化应用程序时由内存管理回收。

您是否通过尽量减少和最大化您的应用程序来提高内存管理或应用程序性能? 不。您可以找到一些.Net Windows程序员,他们添加代码以最小化,然后最大化他们的程序,认为他们正在优化内存。 由于这些程序员与其他人分享了这种技术,一个.Net都市传奇就诞生了 – 一个基于小说而不是事实的编程实践。 这种做法是不必要的,因为当操作系统需要留下未使用的内存时,加载程序集会自动回收它。 事实上,当内存充足时,减小应用程序工作集的大小可能会降低性能。

而不是看任务管理器,你应该使用PerfMon工具来查看你的应用程序的内存消耗。 你会看到真实的记忆检查这个柜台:

Process-> VirtualBytes:虚拟字节是进程正在使用的虚拟地址空间的当前大小(以字节为单位)。 使用虚拟地址空间不一定意味着相应地使用磁盘或主内存页面。 虚拟空间是有限的,这个过程会限制它加载库的能力。

.NET中的垃圾收集发生在所有对象死亡或关闭程序时。 你也可以在.NET中调用垃圾回收器,但通常不会这样做。 尽管在最小化模式下,程序虽然工作(或者活着或者任何你可以调用的),但是没有被用户关注或者被主动使用。 因此,被分配给程序的内存使用(系统资源)减少,所以其他程序可以使用系统资源。

你如何确定你的程序使用的内存量?

我相信Windows窗体被称为调用SetProcessWorkingSetSize从RAM尽可能多的页面驱逐。