.net WPF内存泄漏
我有一个我自己没有创建的WPF表单,所以我不太擅长WPF。但它的泄漏非常严重,高达400 MB,关闭表单也无济于事 问题在于我的应用程序一次加载所有图片。我只想加载那些目前可见的。它大约有300张图片,它们有点大,所以我的WPF表单在加载它们时会遇到麻烦 我有一个带有我自己类型的.net WPF内存泄漏,.net,wpf,performance,memory-leaks,.net,Wpf,Performance,Memory Leaks,我有一个我自己没有创建的WPF表单,所以我不太擅长WPF。但它的泄漏非常严重,高达400 MB,关闭表单也无济于事 问题在于我的应用程序一次加载所有图片。我只想加载那些目前可见的。它大约有300张图片,它们有点大,所以我的WPF表单在加载它们时会遇到麻烦 我有一个带有我自己类型的DataTemplate,它有一个属性缩略图。模板中的代码如下所示: <Image Source="{Binding Path=Thumbnail}" Stretch="Fill"/>
DataTemplate
,它有一个属性缩略图
。模板中的代码如下所示:
<Image Source="{Binding Path=Thumbnail}" Stretch="Fill"/>
然后我有一个带有控件的网格,控件的源代码是上面的模板。此控件的代码如下所示。请为我提供一些提示,告诉我如何优化代码,并可能获得唯一可见的代码,同时只加载那么多控件
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Controls:ElementFlow">
<Grid Background="{TemplateBinding Background}">
<Canvas x:Name="PART_HiddenPanel"
IsItemsHost="True"
Visibility="Hidden" />
<Viewport3D x:Name="PART_Viewport">
<!-- Camera -->
<Viewport3D.Camera>
<PerspectiveCamera FieldOfView="60"
Position="0,1,4"
LookDirection="0,-1,-4"
UpDirection="0,1,0" />
</Viewport3D.Camera>
<ContainerUIElement3D x:Name="PART_ModelContainer" />
<ModelVisual3D>
<ModelVisual3D.Content>
<AmbientLight Color="White" />
</ModelVisual3D.Content>
</ModelVisual3D>
<Viewport2DVisual3D
RenderOptions.CachingHint="Cache"
RenderOptions.CacheInvalidationThresholdMaximum="2"
RenderOptions.CacheInvalidationThresholdMinimum="0.5"/>
</Viewport3D>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
仅凭代码片段很难缩小问题的范围。如果还没有,您可能会想要。所描述的“ElementFlow”控件是否相同?控件似乎是,所以我不希望它访问不可见项的缩略图属性
您如何对公开“缩略图”属性的数据结构进行建模?您能将其设置为属性需求在第一次访问时加载缩略图吗?也许通过一个后备缓存(在一段时间内保持缩略图加载)来实现这一点可以解决这个问题
编辑
我可能已经假设了一些我不应该做的事情。在阅读我链接的第二篇文章的评论时,我现在认为可能是ElementFlow控件的公开版本实际上没有实现虚拟化。也许您可以记录对“缩略图”属性的访问,并确定是否针对不可见的元素访问该属性。当您试图在.NET应用程序中查找内存泄漏时,首先要查看的是订阅事件的对象(WPF与否) 如果对象X正在侦听由对象Y引发的事件,则Y将保留对X的引用。无论您实现了何种虚拟化(或处置)方法,如果X没有取消订阅Y的事件,X将和Y一样留在对象图中,并且永远不会最终确定和垃圾回收。(即使它实现了
IDisposable
,并且您显式地对其调用Dispose
)
当你说“关闭表单没有帮助”时,这让我倍感怀疑:我希望有人在窗口
对象上实现了一个object属性,并且该对象订阅了某种事件。因此关闭窗口,但它仍然存在于对象图中,因为它的一个属性正在被引用
(让您了解这可能有多隐蔽:WinFormsToolStrip
控件在Windows主题更改事件可见时会订阅这些事件。这很好,因为更改计算机的主题会自动反映在正在运行的应用程序的UI中。如果您取消引用ToolStrip 如果不首先将Visible
设置为false,它将继续接收主题更改事件,直到应用程序终止。)
内存分析器可以帮助实现这一点-这就是我发现我的应用程序内存中有数千个ToolStrip
对象的原因,尽管我认为这些对象都已被销毁。谢谢。我检查并验证了缩略图属性的检索次数与列表中的项目数相同。是的,这就是我使用的控件我正在使用:)。听起来他发现了同样的事情。实施虚拟化有多难…?:)+1:我公司的WPF应用程序每次生成新页面时都会泄漏兆字节的内存,我们都认为这是WPF的错误。突然打开探查器,发现每个页面都连接到静态事件处理程序,但从未取消连接,从而导致灾难性(且易于修复)泄漏。