【问题标题】:How to create a memory leak in C# / .NET [duplicate]如何在 C#/.NET 中创建内存泄漏 [重复]
【发布时间】:2011-09-27 21:59:39
【问题描述】:

可能的重复:
Is it possible to have a memory leak in managed code? (specifically C# 3.0)
Memory Leak in C#

昨天有一个类似的问题,但是对于 Java,所以我很感兴趣 - 在 C#/.NET 中创建内存泄漏需要什么(不使用 unsafe)?

【问题讨论】:

标签: c# .net memory-leaks


【解决方案1】:

当一个对象订阅一个事件时,暴露该事件的对象会维护一个对订阅者的引用(实际上,事件,MultiCastDelegate 最初是这样做的,但它是通过的)。如果对它的最后一个引用(event 维护的除外)超出范围,此引用将阻止 订阅者 被 GC。

其他两个答案的情况完全倒退,不正确。这在一个简单的示例中显示有点棘手,通常在较大的项目中看到,但请记住,对 subscriber 的引用由 MultiCastDelegate (event) 维护,您应该能够想通。

编辑:正如 Marc 在他的回复中提到的那样,从技术上讲,您可以通过 GetInvocationList() 方法获得对“泄漏”对象的引用,但是您的代码不太可能使用它,并且当您崩溃时也没关系OutOfMemoryExcetion.

【讨论】:

  • 非常正确,我完全同意 - 但我们应该记住,这并不能回答问题
  • @Adam Ralph:不是吗?它描述了一种泄漏内存的方法。这如何避免回答问题?
  • 我不同意您描述的是内存泄漏。内存泄漏意味着 GC 已损坏,因为它没有释放无根对象使用的所有内存。在您描述的情况下,引用和生命周期得到了正确维护,并且 GC 保持了所有对象的活动状态。
  • 让我有点好笑的是,投票最高的答案实际上是对两个与事件相关的答案的评论(其中一个现在已被删除,顺便说一句,所以“其他两个答案”点有点令人困惑,并且可能被认为是指我的事件相关答案,它向后)
  • @Marc:嗯,当我发布这个时,它是唯一正确的。我的电脑比你早两分钟显示这个帖子,但即使你是第一个,我发帖时也没有看到。该死的,必须有人把它弄好! =D 我删除了现在不相关的部分。
【解决方案2】:

静态事件;致命,因为它们永远不会超出范围。

static event EventHandler Evil;

for(int i = 0 ; i < 1000000 ; i++)
    Evil += delegate {};

匿名方法在这里只是一个不错的选择,但很不错,因为它们也是是取消订阅的猪,除非您将副本复制到变量/字段中并订阅 /em>。

技术上这实际上并没有“泄露”,因为您仍然可以通过 Evil.GetInvocationList() 访问它们 - 但是,当与常规对象一起使用时,这可能会导致意外的对象生命周期,即

MyHeavyObject obj = ...
...
SomeType.SomeStaticEvent += obj.SomeMethod;

现在obj 的对象永远存在。这足以满足感知到的泄漏 IMO,并且“我的应用死于可怕的死亡”对我来说已经足够了;p

【讨论】:

  • 但你仍然可以得到它们......不是吗?
  • 是的,我必须在此之前一次修复此问题...恰好一次,因为这不会再次发生 =)
  • @Adam Ralph:所有订阅者都将被无限期保留(除非未从活动中注册),因为活动是静态的。
  • @Adam - 对此进行了澄清
  • 好的,我认为这实际上只是归结为“什么是内存泄漏”辩论;-)。我可以看到@Marc 和@Ed 的两点。我想我对我认为是真正的内存泄漏的事情更加挑剔。我仍然相信您所描述的情况不是内存泄漏,而是一种导致意外对象生命周期的方法。假设两者具有相同的最终效果。
【解决方案3】:

直接内存访问是从安全托管代码中抽象出来的。必须在某处调用不安全代码以引发内存泄漏,无论是在您编写的代码中还是在具有内存泄漏错误的第 3 方资源(可能在 FCL 中)中。

【讨论】:

    猜你喜欢
    • 2011-11-06
    • 2013-12-25
    • 1970-01-01
    • 2022-12-06
    • 2011-09-22
    • 2013-04-21
    相关资源
    最近更新 更多