我已经问过question我在WPF中的内存管理问题,但这是一个关于同一问题的不同问题。 我正在使用DotTrace试图弄清楚发生了什么。当我启动我的应用程序时,我可以在任务管理器中看到它需要200MB。 DotTrace说总共33MB。如果我只是最小化窗口并将其重新启动,则根据TM的内存占用大约为25MB。
我有一个显示人名和图片的ListBox。它显示多达3000人(我将处理分页,但这不是重点)。当我向下滚动时,我可以在TM中看到内存迅速增加。如果我只是继续向上和向下滚动内存快速达到1GB。在滚动期间,基础数据没有变化,也没有我自己的事件。如果我最小化窗口并将其重新启动,内存将从1GB降至25MB。
在最小化并看到TM中的内存消失之前,我使用DotTrace创建了快照,它显示的内存量与滚动前相同 - 大约30MB左右。
有人可以向我解释当应用程序最小化时内存会发生什么变化吗?任务管理器中显示的数字是否可信?
由于
PS1: 如果我将这个添加到我的ListBox中,则行为没有变化:
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Recycling"
PS2: 我已经放了一个带代码的按钮,如果有任何东西(它从700MB减少到680MB),GC就不会回收:
GC.Collect();
GC.WaitForPendingFinalizers();
答案 0 :(得分:2)
不能给你一个确定的答案,但有些事情要指出:
DotTrace仅显示托管内存使用情况。它看起来你的应用程序正在使用大量非托管内存(可能由WPF本身为所有这些图像分配)。
最小化进程通常不会释放任何内存,只是将其分页,以便其他应用程序可以使用它。在这种情况下,这是一个红色的鲱鱼。
了解.Net的分代垃圾收集是如何运作的。
在您的流程达到操作系统设置的资源限制之前,它不一定会释放已分配给它的任何内存。
使用Windows内置的性能计数器。它们将显示比DotTrace更有用的应用内存整体细分,包括托管和非托管内存。
DotTrace很糟糕。得到ANTS或其他东西。我喜欢ReSharper,但Jetbrains真的不应该为DotTrace收费,这很可悲。
编辑:4)有点误导 - .Net的内存管理器可以出于其他原因释放内存(当一代人已满,对于初学者而言)。
答案 1 :(得分:0)
如果您使用的是虚拟化容器,则会在滚动时动态创建可视对象。这反过来可能会导致对GC的一些骚扰,因为你很快就会创建相当粗糙的对象。一旦你最小化,我会假设GC正在开始并收集所有这些可视对象。
编辑:
看到您的修改后,您可能需要尝试将IsVirtualizing
设置为false
进行测试。默认值为true
,因此省略它不会改变任何内容。