小编Ali*_*son的帖子

WeakEventManager 和 Destructor 的内存保留问题

我遇到了与 WeakEventManager 的使用相关的内存保留问题。使用 DotMemoryProfiler 对我的应用程序进行分析后,我发现每当我使用以下命令添加处理程序时WeakEventManager.AddHandler,都会导致向 ConditionalWeakTable<object, object> 添加一个实例,并且该条目将被保留,除非手动删除该处理程序(即使在析构函数中删除也不会\ xe2\x80\x99t 工作,你必须有一个函数来显式删除它)。

\n

从下面的代码中,您可以看到手动调用 Detach 方法与通过析构函数调用它是有区别的。手动调用时,ConditionalWeakTable 会被正确收集并在 DotMemoryProfiler 快照中标记为“Dead”。然而,当从析构函数 ( ) 调用它时~Subscriber,ConditionalWeakTable 仍然存在。请注意,快照是在执行 Detach 之后拍摄的(因为序列打印在控制台中)。我还确保它在发布模式下运行,并且未选中“抑制 JIT 优化”选项

\n

这是显示幸存对象的 DotMemory 快照的比较:

\n

在此输入图像描述

\n

您可能认为幸存的字节不多\xe2\x80\x99,但这在我们的实际应用程序中引起了问题,因为我们广泛使用 Wea​​kEventManager 并通过析构函数取消订阅它,导致保留大量内存(超过12MB)。\n这是一个示例的屏幕截图,它可以在我们的实际应用程序中保留如此巨大的内存量。

\n

在此输入图像描述

\n

为了提供更多上下文,这里是相关的代码片段:

\n
class Program\n{\n    static void Main()\n    {\n        var isolator = new Action(() => { \n            var publisher = new Publisher();\n            var subscriber = new Subscriber();\n\n            subscriber.Init(publisher);\n            MemoryProfiler.GetSnapshot();\n\n            //subscriber.Detach(publisher); // detach it manually won\'t cause issue\n      });\n            isolator();\n\n …
Run Code Online (Sandbox Code Playgroud)

c# weakeventmanager

5
推荐指数
1
解决办法
318
查看次数

标签 统计

c# ×1

weakeventmanager ×1