Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net WPF MVVM Prism应用程序内存泄漏_.net_Wpf_Memory Leaks_Garbage Collection_Prism 4 - Fatal编程技术网

.net WPF MVVM Prism应用程序内存泄漏

.net WPF MVVM Prism应用程序内存泄漏,.net,wpf,memory-leaks,garbage-collection,prism-4,.net,Wpf,Memory Leaks,Garbage Collection,Prism 4,我有一个使用MVVMPrism编写的WPF应用程序。它有很多标签。这些选项卡每个都消耗大约2..3 MB的内存。客户机抱怨说,在打开和关闭几十个选项卡之后,应用程序消耗的内存要比它从一开始就消耗的内存多得多。此外,打开新选项卡需要更多内存,所以应用程序不使用旧选项卡,而是创建新选项卡 所以很明显,旧的标签页不会被垃圾收集。很明显,因为有一些链接指向它们 我该如何收集垃圾呢?我是否应该实现IDisposable,并删除所有可能的引用?并确保Dispose方法也在析构函数中调用?我不确定是否可以删除

我有一个使用MVVMPrism编写的WPF应用程序。它有很多标签。这些选项卡每个都消耗大约2..3 MB的内存。客户机抱怨说,在打开和关闭几十个选项卡之后,应用程序消耗的内存要比它从一开始就消耗的内存多得多。此外,打开新选项卡需要更多内存,所以应用程序不使用旧选项卡,而是创建新选项卡


所以很明显,旧的标签页不会被垃圾收集。很明显,因为有一些链接指向它们

我该如何收集垃圾呢?我是否应该实现IDisposable,并删除所有可能的引用?并确保Dispose方法也在析构函数中调用?我不确定是否可以删除所有不需要的引用


也许有一个很好的工具可以帮助我解决这个问题?

这显然是一个很难回答的问题。内存消耗可能不仅仅是由内存泄漏引起的!每个应用程序都是不同的,没有银弹,所以这里有一些想法可能会有所帮助

  • 获取ANTS profiler,它有2周的试用期+很棒的教程。它会指向很多东西,比如zomby对象等等

  • WPF是一个猪,所以你打开的标签越多(不消失的控件),它占用的内存就越多。看看你的XAML,你能把它剪下来吗。例如,使用TextBlock而不是标签。移除额外的嵌套控件,如StackPanel中的StackPanel,或StackPanel中网格中的网格-将所有这些控件放在一个网格中,并利用行/列。。如果您有一个项目模板,其中每个项目都做了一些使其变得复杂的事情,请尝试更改该模板。例如,如果在焦点上,它在项目周围绘制了一个边框,并做了一些有趣的事情,问一个问题,我是否可以从每个项目中删除该边框,并创建一个控件来计算其位置并适当地放置自身

  • 每个选项卡是否有相同类型的视图(usercontrols或控件),只是不同的实例?如果是,你能回收它们吗?一年多前,我参与了一个项目,我们在其中创建了一些菜单,为一些标准创建了一个选项卡,然后是另一个,然后是另一个。条件不同,但视图类型相同。它只是被注入了不同的信息——Prism正在为每个选项卡创建一个新的视图控件,这显然是昂贵的。我们最终要做的是创建不同的ViewModel,但保留该昂贵视图的相同实例(在需要时通过删除/添加回区域进行循环)。 要做到这一点,每个ViewModel都需要导航(示例)

    }

    此链接非常有用:

  • 关于垃圾收集的说明: NET垃圾收集器的全部目的是代表我们管理内存。 但是,在一些非常罕见的情况下,使用GC.Collect()以编程方式强制执行垃圾收集可能是有益的

    具体而言:

    a、 当您的应用程序即将进入一个您不希望被可能的垃圾收集中断的代码块时

    b、 当您的应用程序刚刚完成分配大量对象,并且您希望尽快删除尽可能多的已获取内存时。(我的项目就是这样)

    c。此外:

  • 我肯定会在每个ViewModel上实现Dispose方法,在这里我会将所有big设置为null,不要忘记取消订阅事件,以及计时器之类的东西。您可以调用GC.Collect();但是请阅读上面的注释。。不要忘记清理复杂对象,不要只是将它们设置为null。例如,在我的示例中,我们有如下内容:

    ClearDisplayGrid ();
    
    这反过来又在做:

    private void ClearDisplayGrid ()
        {
            foreach (var r in DisplayGrid.MyItems.SelectMany (it => it.SubItems))
            {
                r.IsSelectedChanged -= ReadingIsSelectedChanged;
                r.InEditChanged -= ReadingInEditChanged;
                r.PropertyChanged -= ReadingPropertyChanged;
            }
        }
    

    这显然是一个很复杂的问题。内存消耗可能不仅仅是由内存泄漏引起的!每个应用程序都是不同的,没有银弹,所以这里有一些想法可能会有所帮助

  • 获取ANTS profiler,它有2周的试用期+很棒的教程。它会指向很多东西,比如zomby对象等等

  • WPF是一个猪,所以你打开的标签越多(不消失的控件),它占用的内存就越多。看看你的XAML,你能把它剪下来吗。例如,使用TextBlock而不是标签。移除额外的嵌套控件,如StackPanel中的StackPanel,或StackPanel中网格中的网格-将所有这些控件放在一个网格中,并利用行/列。。如果您有一个项目模板,其中每个项目都做了一些使其变得复杂的事情,请尝试更改该模板。例如,如果在焦点上,它在项目周围绘制了一个边框,并做了一些有趣的事情,问一个问题,我是否可以从每个项目中删除该边框,并创建一个控件来计算其位置并适当地放置自身

  • 每个选项卡是否有相同类型的视图(usercontrols或控件),只是不同的实例?如果是,你能回收它们吗?一年多前,我参与了一个项目,我们在其中创建了一些菜单,为一些标准创建了一个选项卡,然后是另一个,然后是另一个。条件不同,但视图类型相同。它只是被注入了不同的信息——Prism正在为每个选项卡创建一个新的视图控件,这显然是昂贵的。我们最终要做的是创建不同的ViewModel,但保留该昂贵视图的相同实例(在需要时通过删除/添加回区域进行循环)。 要做到这一点,每个ViewModel都需要导航(示例)

    }

    此链接非常有用:

  • 关于垃圾收集的说明: NET垃圾收集器的全部目的是代表我们管理内存。 但是,在一些非常罕见的情况下,使用GC.Collect()以编程方式强制执行垃圾收集可能是有益的

    具体而言:

    a、 当您的应用程序即将进入一个您不希望被可能的垃圾收集中断的代码块时

    b、 当应用程序刚刚完成分配大量对象时
    private void ClearDisplayGrid ()
        {
            foreach (var r in DisplayGrid.MyItems.SelectMany (it => it.SubItems))
            {
                r.IsSelectedChanged -= ReadingIsSelectedChanged;
                r.InEditChanged -= ReadingInEditChanged;
                r.PropertyChanged -= ReadingPropertyChanged;
            }
        }