我有一个WPF应用程序,可以在网格中显示图像。用户可以通过在单击鼠标左键的同时移动鼠标来快速滚动浏览图像。因此,这意味着有很多图像在快速变化。
我注意到24个和40个元素大小的网格(最大)的性能下降。我发现减速的原因是大量垃圾被创建,从而导致大量的gen0和gen1垃圾收集受阻。通过减少分配量,我可以将性能从大约10 fps提升到25 fps。
仍然对此不完全满意,我进行了更多分析,发现有大量Action对象正在生成,远远超过了所有其他分配的类型。滚动时,我每秒获得约50000个动作分配。
我使用内存探查器进一步跟踪了此事件,原因是一个PropertyChanged事件,该事件在每次图像更改时都会触发。这在内部导致一些事件被注册和注销,该事件管理器使用类ReaderWriterLockWrapper。实际上,每次访问WriteLock或ReadLock属性时,都会分配一个Action,如参考源所示:
CallWithNonPumpingWait(()=>{_rwLock.EnterWriteLock();});
我注意到从4.7版开始,代码就是这种方式。这是故意的吗?当我连续滚动8秒时,仅此一项就在我的应用程序中导致了16MB的Action实例。另外,按照我的看法,此lambda可能只是实例成员。
答案 0 :(得分:0)
.NET 4.8通过启用EnableWeakEventMemoryImprovements解决了该问题