C# 为什么我的Winforms程序保留了这么多虚拟内存?

C# 为什么我的Winforms程序保留了这么多虚拟内存?,c#,memory,.net-4.0,C#,Memory,.net 4.0,我有一个C#/.NET4.0应用程序,当我启动它时,它会显示两个窗口,其中有十几个控件。当我运行我的程序(调试或发布不重要),甚至在我做任何事情之前,我在任务管理器/资源监视器中看到我的程序已经有超过450MB的私有内存。我意识到任务管理器不是衡量内存使用情况最可靠的方法,但它是我的用户最容易看到的方法之一 当我运行VS2010.NET内存分配性能分析时,对于整个程序的运行,它报告了为托管对象实际分配的大约5MB内存(我的程序通常也使用一些非托管对象,但它们非常小,为了简化此调查,我禁用了它们,

我有一个C#/.NET4.0应用程序,当我启动它时,它会显示两个窗口,其中有十几个控件。当我运行我的程序(调试或发布不重要),甚至在我做任何事情之前,我在任务管理器/资源监视器中看到我的程序已经有超过450MB的私有内存。我意识到任务管理器不是衡量内存使用情况最可靠的方法,但它是我的用户最容易看到的方法之一

当我运行VS2010.NET内存分配性能分析时,对于整个程序的运行,它报告了为托管对象实际分配的大约5MB内存(我的程序通常也使用一些非托管对象,但它们非常小,为了简化此调查,我禁用了它们,但没有显著效果)。同样,如果在显示主窗体后从psapi.dll调用EmptyWorkingSet(),我的私有内存将降至~3.5 MB

我已经研究了关于内存占用和内存不足的问题,但这些问题似乎涉及到显示为几十兆字节的程序。我的程序显示了几乎500MB,这看起来更令人担忧

我无法想象所有这些都来自头顶;为什么VS分析器和任务管理器之间存在如此巨大的差异

更新:有趣的是,如果我注释掉InitializeComponent()中设置图像列表的部分,任务管理器中的数字将保持在10MB以下。我有两组PictureBox和ImageList,其中PictureBox根据单选按钮组中的哪个单选按钮显示四个图像中的一个

这些代码行似乎触发了大规模内存增加:

// 
// directionImageList
// 
this.directionImageList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("directionImageList.ImageStream")));
this.directionImageList.TransparentColor = System.Drawing.Color.White;
this.directionImageList.Images.SetKeyName(0, "Dir1.png");
this.directionImageList.Images.SetKeyName(1, "Dir2.png");
this.directionImageList.Images.SetKeyName(2, "Dir3.png");
this.directionImageList.Images.SetKeyName(3, "Dir4.png");
// 
// modeImageList
// 
this.modeImageList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("modeImageList.ImageStream")));
this.modeImageList.TransparentColor = System.Drawing.Color.White;
this.modeImageList.Images.SetKeyName(0, "Mode1.png");
this.modeImageList.Images.SetKeyName(1, "Mode2.png");
this.modeImageList.Images.SetKeyName(2, "Mode3.png");

我使用的是图像列表,所以我可以使用透明度。模式映像为100x100,占用空间考虑到可用资源,.Net framework设计为尽可能快地运行。只有在您专门调用垃圾收集器或其他应用程序需要占用的资源时,应用程序才会继续消耗越来越多的内存(并且随时可用)

最小化应用程序,您应该可以更好地显示应用程序正在使用的内存量

如果您随后继续使用它,它将保持在较低的资源状态,直到被使用并再次使用。再次最小化以查看实际(未)再次使用了多少。这是内置在.net Framework内存管理系统中的。

首先,您尝试过吗?它将分析进程的转储,并给出一些漂亮的内存图,这可能会帮助您找出是谁分配了所有内存


此外,请检查以确保编译的.exe或任何引用/加载的程序集都不是非常大-完全可能所有~500MB都只是加载了DLL。如果(例如)程序集中嵌入了大量资源,则可能会发生这种情况。

有人解释了内存从34 MB跳到145 MB的几个原因:

png已经透明了。只需将白色设置为透明颜色并保存图像。然后正常使用它们。

我自己处理这个问题的经验是,我在imageList中设置了24位图像,而在imageList的设置中设置了32位选项

我在imagelist的属性中设置了24位,问题就解决了。这似乎是一个错误,应该有人将其发布到MS=)


对不起,我的英语太差了。

刚开始这个程序,我的英语容量约为459MB。最小化它可以减少大约1兆字节。我的意思是,我可以理解它是否已经运行了很长一段时间,我分配了很多东西,但我很困惑,为什么一开始就保留了这么多。特别是当VS分析器说我实际上没有分配那么多的时候。这是一个超过450MB的差异,所以有点不对劲。海报上说450MB不是45MB-虽然你说的是真的,但如此大量的内存被消耗这一事实肯定表明存在某种问题。你的UI是否使用图形。或者在用户控件上使用透明背景进行绘制。。。。你在GUI中分配了很多对象吗?我的应用程序在使用超过一亿内存时也遇到了同样的问题。然而,我的应用程序被最小化,并下降到20兆。然而,我在内存中处理大量的大文件,我的计算机有8个可用的Gig。因此,我们采取了现有的措施来提高性能。初始加载听起来可能是应用程序所需资源的问题。。。。可执行文件有多大?在所有按钮、面板、菜单项和其他东西之间,我有大约80个对象,其中一半是标签。我确实有一些透明的图形-磁盘上所有PNG文件的总大小都小于1MB。最大的图片大小约为150x150。我确实注意到VS Profiler包含了我加载的所有图片资源,当时它说我的程序分配了5MB,所以我也不这么认为。任务管理器不是测量内存的最复杂的方法,但它使用性能计数器,因此它应该与任何其他机制一样精确。请注意,任务管理器中的“内存使用情况”列是专用内存使用情况-您可以在“选择列”下添加“虚拟内存大小”列(或仅使用
perfmon.exe
),实际上Visual Studio profiler在这种情况下非常有用。我现在正尝试签出调试诊断。如上所述,我的exe文件大小为568KB。我从四个非托管DLL导入了一些函数,这些DLL没有嵌入到我的程序中,总大小约为1MB。我引用了Excel Interop的东西,但仅此而已。@Troyen(在Priyank链接的帖子中提到)看起来也对这类事情非常有用。我最初有一个imagelist,因为我无法获得一些