1

我有一个使用大量内存的应用程序,但现在我无法改变这个事实。我的问题是我有一个我想执行的操作并提供一个进度对话框,但似乎显示 xaml 进度窗口导致GC.Collect被调用 10 次!有什么想法可以优化打开进度窗口吗?

根据我的 Ants Profiler,导致 GC.Collect 的调用是

System.Window.ShowDialog() ->
..
..
System.Windows.Media.Imaging.BitmapSource.CreateCachedBitmap ->
SafeMILHandle.UpdateEstimatedSize ->
SafeMILHandleMemoryPressure.ctor ->
MemoryPressure.Add ->
MemoryPressure.ProcessAdd ->
GC.Collect
4

4 回答 4

2

还有一个解决方案可以完全禁用与位图图像相关的内存压力和后续的垃圾收集。这更像是一种 hack,但您可以在此处阅读类似的问题。

typeof(BitmapImage).Assembly.GetType("MS.Internal.MemoryPressure").GetField("_totalMemory", BindingFlags.NonPublic | BindingFlags.Static).SetValue(null, Int64.MinValue / 2); 

这样您就可以避免搜索整个代码来查找和修改 WPF 图标初始化。System.Windows.Forms.Integration.ElementHost最重要的是,无论您如何初始化,某些控件都会隐式添加与位图相关的内存压力。

于 2015-10-16T18:43:40.973 回答
1

您是否检查过与该主题相关的其他 stackoverflow 问题?您可能会使用一些提示:

如何避免实时 .NET 应用程序中的垃圾收集?

于 2013-01-29T20:46:45.117 回答
1

这是 WPF 中的错误/功能:

https://connect.microsoft.com/VisualStudio/feedback/details/687605/gc-is-forced-when-working-with-small-writeablebitmap

http://referencesource.microsoft.com/#PresentationCore/Core/CSharp/MS/Internal/MemoryPressure.cs

编辑:自 .NET 4.6.2 以来, MemoryPressure 类已被删除。

于 2015-09-02T12:51:46.683 回答
0

垃圾回收是由 WPF 图标的初始化引起的。当我从 xaml 中删除 icon 属性时:

<Window ... Icon="/CommonUI;component/Common/ProgressReporting/MyIcon.ico">

而是在构造函数中初始化它:

public ProgressWindow()
        {
            InitializeComponent();
            Icon = Properties.Resources.MyIcon.ToImageSource();
        }

问题消失了。

System.Window.UpdateIcon()期间不再调用的差异ShowDialog()。该调用正在为图标文件中的每个图像大小UpdateIcon()创建一个,该文件又在调用,并且由于应用程序的高内存使用率正在为创建的每个新位图调用。CachedBitmapMemoryPressure.AddGC.Collect

当在应用程序中加载大型项目时,这个小改动将我的进度对话框的加载时间减少了 15 秒!

于 2013-01-30T13:40:08.933 回答