首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WPF内存泄漏

WPF内存泄漏
EN

Stack Overflow用户
提问于 2010-05-19 04:37:26
回答 3查看 1.6K关注 0票数 4

我有一个WPF表单,不是我自己创建的,所以我不太擅长WPF。它泄漏很严重,高达400MB,关闭表单也无济于事。

问题出在我的应用程序一次加载所有图片。我只想加载那些目前可见的。它大约有300张图片,它们有点大,所以我的WPF-form无法加载所有图片。

我有一个自己类型的DataTemplate,它有一个Thumbnail属性。模板中的代码如下:

代码语言:javascript
复制
            <Image Source="{Binding Path=Thumbnail}" Stretch="Fill"/>

然后我有一个网格,它有一个控件,上面的模板作为源。此控件的代码如下所示。请向我提供关于如何优化代码的提示,也许可以获得唯一可见的代码,并且同时加载那么多的控件?

代码语言:javascript
复制
    <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>
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-05-19 04:59:19

“ElementFlow”控件和here描述的是同一个控件吗?控件似乎是already using virtualization的,所以我不希望它访问不可见项的缩略图属性。

你是如何对暴露“缩略图”属性的数据结构建模的呢?您是否可以将其设置为属性在第一次访问时按需加载缩略图?也许使用一个后备缓存(它可以在一段时间内加载缩略图)来实现这一点可以解决这个问题。

编辑

我可能假设了一些我不应该做的事情。在阅读我链接的第二篇文章的评论时,我现在认为可能是ElementFlow控件的公开版本实际上并没有实现虚拟化。也许你可以记录对“缩略图”属性的访问,并确定不可见元素是否可以访问该属性。

票数 2
EN

Stack Overflow用户

发布于 2010-05-19 08:48:36

当您试图查找.NET应用程序中的内存泄漏时,首先要查看的是订阅事件的对象。

如果对象X正在侦听由对象Y引发的事件,则Y持有对X的引用。无论您实现什么虚拟化(或处置)方法,如果X不取消订阅Y的事件,那么X将像Y一样一直留在对象图中,并且永远不会被完成和垃圾回收。(即使它实现了IDisposable,并且您显式地对其调用了Dispose。)

当您说“关闭窗体无济于事”时,这让我更加怀疑:我认为有人已经在Window对象上实现了一个对象属性,并且该对象已经订阅了某种事件。因此,您关闭了窗口,但它仍然存在于对象图中,因为它的一个属性正在被引用。

(为了让您了解这可能有多隐蔽:在主题更改事件变得可见时订阅WinForms ToolStrip控件。这很棒,因为更改计算机的主题会自动反映在正在运行的应用程序的UI中。这不是很好,因为如果您在没有首先将Visible设置为false的情况下取消引用ToolStrip,它将继续接收主题更改事件,直到应用程序终止。)

内存分析器可以帮助解决这个问题--这就是为什么我发现我的应用程序在内存中有数以千计的ToolStrip对象,尽管我认为它们都已经被销毁了。

票数 4
EN

Stack Overflow用户

发布于 2010-05-19 04:48:01

仅仅使用您的代码片段很难缩小问题的范围。如果您还没有使用Visual Profiler,那么您可能想要这样做。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2860965

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档