.NET WinForm内存消耗

问题描述:

我一直在使用“.NET Memory Profiler”来分析WinForm的应用程序。.NET WinForm内存消耗

根据windows任务管理器的说法,我似乎无法理解我的应用程序如何增长到1GB,然后是2GB,然后是3GB的使用情况。

使用该工具的专用字节和“所有堆中的总字节数”仅显示为70MB左右。在我的挂件实例列表的顶部,它们大部分是String,或者WeakReference是很多小对象。

所有的应用程序正在做的是显示从数据库加载数据的表单。我重复约100次的形式的显示/处理循环,并且增长是连续的。

我试着约3现在内存分析工具和他们都不给我看这个地方巨大的内存占用量是从哪里来的。

任何人都可以帮助或猜测它可能是什么?

谢谢。

+0

您是从您的IDE分析可执行文件或调试版本吗? – taylonr 2011-04-19 20:56:49

+0

我正在调试内置调试模式的EXE,而不是通过IDE。 – 2011-04-19 20:57:32

+1

这实际上是一个用vb.net编写的应用程序吗?然后WeakReference泄漏预计。 – 2011-04-19 21:07:51

我发现,高CPU负载的垃圾收集往往变得非常低的优先级,以负责清理未使用的内存将只关火.NET库时,他们绝对有必要,尽管引用计数的下一个管理对象将归零。如果有可能尽量把你的代码一些故意的Thread.Sleep调用简单地接受一个事实,即它是一个记忆体猪和希望,逻辑将允许你的系统运行,将有“奇”内存使用情况,你从来没有说过任何事情都会中断,它只是具有虚幻的内存空间。

根据windows任务管理器,我似乎无法理解我的应用程序如何增长到1GB,然后是2GB,然后是3GB的使用情况。

这是因为从任务管理器中的计数器是“工作集”苔丝Ferrandez在this article

指出,有一个叫 工作一套简化的另一个柜台由多少内存在 当前或最近被 进程中的线程所触及的内存或近似 进程 所使用的内存当前在RAM中的内存量。工作组 计数器可能是有趣的,如果你 有太多的分页和 在同一个盒子 竞争有关的RAM许多工艺问题,但为了 确定多少内存是使用 (保留或定向)它 提供很少或根本没有帮助。

MSDN article工作集(重点煤矿)

工作集

这套内存页面 (分配给一个 进程的内存区域)最近使用的线程 在一个过程中。如果 上的可用内存超过指定的 阈值,则页仍保留在进程的工作集中,即使它们未被使用。当可用内存低于指定阈值 时,从工作集中删除的页面为 。如果需要这些 页面,他们将 退回到工作集合 之前他们离开主内存并且 可用于其他进程 使用。

+0

感谢康拉德。我无法理解的是,当Windows只运行在最大3GB的RAM盒上时,它如何让它消耗大量的RAM。随着Visual Studio的开放和其他许多事情的发展,它肯定会溢出可用RAM的数量。我从来没有见过这种非托管语言的行为,肯定是不合理的?运行数天的Visual Studio平均为我消耗400mb。 – 2011-04-19 21:27:22

+1

@MeshMan我的猜测是,你没有任何其他进程竞争RAM,所以它不修剪工作集,你可能有一个非常大的页面文件 – 2011-04-19 22:02:57

这是VB.NET应用程序的一个已知问题吗?

是的。这是Edit + Continue支持编译到可执行文件中的副作用。它受到WithEvents关键字声明的任何事件的影响。 WeakReference跟踪这些事件实例。问题是,如果您在没有调试器的情况下运行应用程序,那些WeakReference会泄漏。进程消耗内存的速率高度依赖于创建类的多少个实例。每个对象每个事件泄漏16个字节。

解决方法很简单,不是而是在没有调试器的情况下使用应用程序的Debug版本。只使用发布版本。当然,只将发布版本发布给您的客户。

+0

+1。这是一个指向相关[Microsoft知识库文章](http://support.microsoft.com/?kbid=919481)的链接,仅为了完整。它不会给Hans的答案添加任何东西 – MarkJ 2011-04-20 08:31:10

+0

正如你可能知道的那样,在发布版本中,符号调试信息没有被发出,并且代码执行被优化,这样最终可执行文件的大小比调试可执行文件的大小要小。但是,首先检查您在调试和发布配置中指定的设置(如何发出符号调试信息)(右键单击您的win窗体项目 - >属性 - >生成选项卡 ​​- >高级... - >调试信息设置),然后想想你想要他们是什么。 – Manoj 2017-02-10 18:44:44