从内存中删除项目/页面/用户控件

20

我制作了一个Windows手机应用,但不幸的是其中存在一些内存泄漏,因为页面没有被正确地移除。这个问题已经通过使用以下答案解决:

Remove Pages windows phone 其中提到:

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
while (App.RootFrame.RemoveBackEntry() != null) ; //line if you navigate without backkey
base.OnNavigatedTo(e);

this.Dispatcher.BeginInvoke(() =>
{
    GC.Collect();
    GC.WaitForPendingFinalizers();

    this.Dispatcher.BeginInvoke(() =>
    {
        GC.Collect();
        GC.WaitForPendingFinalizers();

        this.Dispatcher.BeginInvoke(() =>
        {
            GC.Collect();
            GC.WaitForPendingFinalizers();
        });
    });

这将从分析器中删除页面引用。但是导航后,内存仍然有所增加。而且增加的内存来源不明显。 因此,我尝试引入一个空白项目,并将其作为星型导航进行导航,如下所示:

enter image description here

这样可以删除多达20 mb的视觉和其他元素。因此,这是一个重大的进展。因此,我希望将功能拆分到不同的项目中,以消除不同功能之间的任何联系并保持低内存使用率。这最终形成以下结构:

  • WebService
  • MainProject
  • SecondaryProject
  • PortableLibrary

我使用可移植库在所有项目之间共享模型。 这影响了每次导航到新项目时,旧项目中的所有内容都会被清除,即每个项目只存在一个元素,这对于内存的改善很重要。但仍然存在一些内存泄漏,但受到限制,这意味着内存仅会增加到一定程度为止。 但是内存来自哪里? 回到分析器:

enter image description here

这表明页面没有被删除,所有元素 .view. 都将通过一个项目中的所有页面的配置代码进行删除。但是内存泄漏类似。

问题

  1. 如何从同一解决方案中的另一个项目中删除页面和元素?
  2. 如何从内存中删除项目?

两个项目之间没有共享的信息,除了它们都可以创建 LibraryOfModels 的版本。因此,在项目边界上没有事件、变量或引用被共享。 但是我无法将它从内存中删除。如果导航仅在一个项目中,则我的顶部代码片段可以将其从内存中删除。由于导航分布在两个项目上,所以问题存在。但在其他领域中,它具有一些内存优势,这就是为什么我想要这种结构的原因。

希望有人能帮忙。 谢谢!

附加测试

我尝试使所有页面成为用户控件,以避免导航。但是多次重新创建它们会产生1-2 Mb的稳定泄漏。因此,项目想法仍然是最佳的选择,因为存在界限。但仍无法将其移出。

仍然希望有得救的骑士;)


2
你确定没有任何事件被附加吗? - Patrick Hofman
我认为在加载页面时,你可以尝试使用单例模式。 - Justin CI
@JestinC.I 我从未使用过它,但是快速阅读后我有以下理解。您可以使用Singleton来强制创建对象的唯一实例,对吗? 如果是这样,它对我没有帮助,因为每个实例只存在一个元素。如果导航仅在一个项目内,则我想要将它们从内存中删除,就像我顶部的代码片段所做的那样。问题存在于导航分布在两个项目上。但是它在其他领域具有一些内存优势,这就是为什么我想要这种结构的原因。 - JTIM
也许你应该确保没有线程/任务/定时器保留对你的视图/视图模型的引用?以防万一,这里有一些关于内存泄漏的有趣文章:WPF应用程序中的内存泄漏管理Windows Store应用程序中的内存 - Wojciech Kulik
1
我脑海中又想到了一件事:您是否使用了一些第三方控件/库、Image、LongListSelector、FlipView 或 WebView(因为它们在内存管理方面存在一些问题)?如果没有任何示例项目,我猜很难找到问题所在。您能否准备一个这样的项目,以便能够重现此问题?如果相同架构的空项目上没有出现此问题,则代码/控件存在一些问题。 - Wojciech Kulik
显示剩余4条评论
3个回答

3

如上述评论所述,我不认为这能解决问题。从您提供的链接中,我看到它只会强制对象的一个元素。但是,根据我在问题中展示的图片,您可以看到只有对象的一个实例。那么,这将如何帮助我从内存中删除现有页面?因为页面位于不同的项目中,仅在内存中保留一个页面的好处已经实现,而且我删除了后堆栈,这影响到每次导航时页面将被重新创建(期望的),但某些页面仍然存在,单例模式如何帮忙呢? - JTIM
单例模式并不能帮助解决问题,它只是确保在内存中只有一个实例。您能否请解释一下,单例模式如何有所帮助? - Joby James
@jobyjames85:单例模式一次只创建一个对象,因此对象处理将变得容易。在某些情况下,如果不使用单例模式并且垃圾收集器未正确处理,则会出现内存泄漏的问题,特别是对于大型程序而言。 - Justin CI

0

查找所有可丢弃的图形/IO,确保在使用完它们后将其处理掉。
所有此类对象都继承自IDispose接口。


0

注意第三方控件/库,如Image、LongListSelector、FlipView或WebView,因为它们在内存管理方面存在一些问题。

您应该确保没有线程/任务/计时器保留对您的视图/视图模型的引用。

有两篇关于内存泄漏的有趣文章:

我想如果没有示例项目,找到根本原因可能会很困难。如果在相同架构的空项目中不发生,则代码存在某些问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接