c# - 在 C# 或 VB.Net 中创建内存泄漏

标签 c# .net vb.net c#-4.0 memory-leaks

灵感来自 this question ,想知道在 .Net 中创建内存泄漏的可能方法是什么。我曾经找到一个带有 ODBC 数据访问的。有没有人对最新版本有任何经验?

编辑:是否有任何看似正常、无害的使用会导致内存泄漏?

最佳答案

造成内存泄漏的最简单方法是滥用为互操作设计的设施,因为它们处理非托管内存。

例如,分配一个指向对象的GCHandle,并且永不释放它。

编辑:是否有任何看似正常、无害的使用会导致内存泄漏?

只有我知道的一个,特别是在一些 UI 程序中。这在 WinForms 中是可能的,但直到最近由于 WPF 和 MVVM 才变得普遍:

许多人忽略的关键点是委托(delegate)包含对其运行的对象的引用。

因此,如果使用带有双向绑定(bind)的 MVVM 等模式(使用事件实现,由委托(delegate)组成),并且如果 View 更改为具有相同 ViewModel 的不同 View,则默认情况下 ViewModel 的更新保持不变绑定(bind)到两个 View ,这会导致旧 View 泄漏。

理论上任何委托(delegate)都可能发生这种情况,但在实践中并不常见,因为订阅者通常比发布者长寿或取消订阅。

取消订阅 lambda 事件处理程序时会出现类似的情况:

timer.Elapsed += (_, __) => myObj.Notify();
timer.Elapsed -= (_, __) => myObj.Notify();

在这种情况下,即使 lambda 表达式相同,它们代表不同的处理程序,因此 Elapsed 事件仍将调用 Notify。上面的第二行没有效果;它不会退订,也不会引发错误。

请注意,不正确的取消订阅通常会在测试期间被发现,因此它们很少会导致发布的代码出现“泄漏”。相比之下,上述 MVVM 情况不会导致任何可观察到的副作用(内存和资源泄漏除外)。

关于c# - 在 C# 或 VB.Net 中创建内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6555024/

相关文章:

vb.net - Entity Framework 和存储库模式

c# - P/Invoke 为目标 DLL 提供的内存是否较少?

c# - 我可以在不写入中间临时存储的情况下获取文件的 GZipStream 吗?

c# - Windows 窗体的 MVP 示例

c# - WPF 模态窗口作为 WinForms 中的工具窗口消失

vb.net - Linq Select withWhere 基于下拉值

c# - 如何使用 System.Text.Json 将 Stack<T> 序列化为 JSON,而不反转堆栈?

c# - 转换时拆分 DateTime 字符串

c# - 在 MVVM 中使用 Rx 跟踪集合更改

c# - 最小化时不显示文档注释