我用C#创建了一个程序。该程序使用了大约60-70 MB的内存。 但是当我最小化该程序时,它需要更少的内存,即只需10 MB。
当我最大化或回到该程序时,它使用了20 MB ......
为什么会这样?
当你最小化程序时,是否会调用垃圾收集器?
答案 0 :(得分:23)
这与垃圾收集无关 - 非.NET程序也会发生这种情况(尝试在查看内存占用时最小化浏览器)。
当您最小化程序时,Windows操作系统将不再需要将UI组件保留在内存中,因此内存要求较低。
那就是 - 当应用程序最小化时,窗口会修剪工作集。
请参阅this channel9主题和此KB article(感谢@Sasha Goldshtein)。
答案 1 :(得分:8)
垃圾收集器在决定运行时运行;这不一定与用户所做的任何事情有关,当然也不会最小化应用程序。通常,您可以将其视为与可用内存总量相比的内存使用量的函数。但重点是,作为一名程序员,这对你来说应该是有些不透明的。垃圾收集相对于手动内存管理的最大好处是您不必担心任何此类问题。
我怀疑你的问题是你正在使用Windows任务管理器来监控应用程序的内存使用情况并确定何时进行垃圾收集。这是一个巨大的错误。如果您确实需要进行内存分析,则需要投资适当的分析器。 任务管理器不是为此而设计的,您经常会得到错误的读取。
更具体地说,当您最小化应用程序时,您似乎看到应用程序消耗的内存量显着减少的原因只是在尝试使用任务管理器进行内存分析时会得到的错误读取之一。实际上,无论何时最小化应用程序,Windows内核都会自动将其正在使用的大部分内存分页。你会看到所有你的应用程序,而不仅仅是用.NET编写的那些。因为任务管理器向您显示当时存在于真实内存中的应用程序正在使用的总内存的子集(即,尚未分页到磁盘的数量),它看起来就像内存使用量减少时,它还没有真正减少。为了获得更准确的读取,您应该查看进程的“私有字节”值。此knowledge base article提供了更多详细信息。
答案 2 :(得分:3)
本文解释了所有:THE MEMORY MYSTERY
这是上述网站的摘录:
.Net Urban Legend
可以减少.Net Windows窗体的工作集大小 通过最小化然后最大化应用程序来应用 加载后立即Windows操作系统修剪了工作集 应用程序最小化时。简要使用的内存 加载前面提到的所有那些组件时,由 最小化和最大化应用程序的过程。您可以 通过创建和运行a来向自己演示此行为 Windows窗体应用程序只有Form1,没有添加代码。
创建并运行简单的应用程序。
打开Windows任务管理器,然后打开其“进程”选项卡。您将看到任务管理器在大约显示应用程序的内存使用情况。 12.5 MB。
- 醇>
现在最小化您的应用程序,然后最大化它。再次检查任务管理器。您将看到任务管理器现在显示您的 应用程序的内存使用量约为1.5 MB。使用的内存 在启动应用程序时加载程序集已被回收 最小化应用程序时的内存管理。
您是否通过最小化和改进内存管理或应用程序性能? 最大化您的申请?不。你可以找到一些.Net Windows 程序员添加代码以最小化然后最大化他们的程序 认为他们正在优化记忆。正如这些程序员所拥有的 与其他人分享了这种技术.Net Urban Legend一直如此 出生 - 一种基于虚构而非事实的编程实践。这个 操作是不必要的,因为当OS需要剩余未使用的内存时 当组件装载后,它将回收它 自动。实际上,减小应用程序的大小 当记忆力充足时,工作集可能会降低性能。
答案 3 :(得分:1)
您应该使用PerfMon工具来查看应用程序的内存消耗,而不是查看任务管理器。您将看到真实内存检查此计数器:
Process-> VirtualBytes:Virtual Bytes是进程正在使用的虚拟地址空间的当前大小(以字节为单位)。使用虚拟地址空间不一定意味着相应地使用磁盘或主存储器页面。虚拟空间是有限的,并且该过程可以限制其加载库的能力。
答案 4 :(得分:0)
当所有对象都已死或关闭程序时,会发生.NET中的垃圾收集。您也可以在.NET中调用垃圾收集器,但通常不会这样做。而在最小化模式下,程序虽然工作(或活着或任何你可以调用的),但并不是用户关注焦点或主动使用的。因此,分配给程序的内存使用(系统资源)会减少,因此其他程序可能会使用系统资源。
答案 5 :(得分:-2)
您如何确定程序使用的内存量?
我相信Windows Forms以调用SetProcessWorkingSetSize
来尽可能多地从RAM中驱逐页面而闻名。