c# - 为什么我的 Winforms 程序会保留这么多虚拟内存?

标签 c# memory .net-4.0

我有一个 C#/.NET 4.0 应用程序,当我启动它时会显示两个窗口,其中包含大约十几个控件。当我运行我的程序(调试或发布无关紧要)时,我什至在其中执行任何操作之前,我在任务管理器/资源监视器中看到我的程序已经拥有超过 450MB 的私有(private)内存。我意识到任务管理器并不是衡量内存使用情况的最可靠方法,但它是我的用户最容易看到的方法之一。

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

我已经看过关于内存占用的问题 herehere ,但这些问题似乎与显示为几十兆字节的程序有关。我的程序显示将近 500MB,看起来更令人担忧。

我无法想象所有这些都来自头顶;为什么 VS profiler 和任务管理器之间会有这么大的差异?

更新:有趣的是,如果我注释掉 InitializeComponent() 中设置 ImageLists 的部分,任务管理器中的数字将保持在 10MB 以下。我有两组 PictureBoxes 和 ImageLists,其中 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");

我正在使用 ImageLists,所以我可以使用透明度。模式图像为 100x100,每个占用小于 26KB 的磁盘空间。方向图像默认为 208x277,磁盘上大约 75KB。我知道 png 是一种压缩格式,但即使在内存中未压缩,我也不希望这七张图片有数百兆字节。

我知道是否存在一些效率低下的问题,是否有另一种方法可以动态显示具有透明度的图片?

结论: ImageList 类有问题。有时它会丢失 alpha channel ,这导致我的程序保留的内存比它需要的多。它还减慢了最初绘制主窗体的时间(在运行时和在设计器中)。

转储两个 ImageList 使我的程序减少到更健康的 10MB RAM。谢谢大家的建议!

最佳答案

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

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

对不起我的英语。

关于c# - 为什么我的 Winforms 程序会保留这么多虚拟内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5656881/

相关文章:

c# - 如何使用 LINQ 确保多个集合具有相同的项目计数

c# - 非托管导出/Delphi/.NET 4/Robert Giesecke

c# - hibernate查询使用nolock时出现识别错误

C#。适用于大数据的可扩展高负载架构

multithreading - MAC OS X Yosemite上的简单多线程程序中的错误访问

c# - 网络共享上的 .NET 4.0 应用程序导致 SecurityException

c# - 开发 html/jquery 座位应用程序的最佳方法(或者我们应该使用 silverlight/flash)

c# - nhibernate 插入问题 - 有 id 但没有实体对象

memory - 确定可以连续分配的最大 GPU 设备内存量

c - 如何在C中写入只读内存中的指针