为什么.NET没有内存泄漏?

Din*_*nah 57 .net memory-leaks

忽略不安全的代码,.NET不会有内存泄漏.我从许多专家那里无休止地读到了这一点,我相信它.但是,我不明白为什么会这样.

我的理解是框架本身是用C++编写的,C++容易受到内存泄漏的影响.

  • 底层框架是如此精心编写的,它绝对没有任何内部内存泄漏的可能性?
  • 框架代码中是否存在自我管理甚至可以解决其自身内存泄漏的问题?
  • 答案是我没有考虑过的其他问题吗?

Ode*_*ded 94

.NET 可能有内存泄漏.

大多数情况下,人们会引用垃圾收集器,它决定何时可以摆脱对象(或整个对象循环).这避免了经典的 c和c ++样式内存泄漏,我的意思是分配内存而不是以后释放它.

但是,很多时候程序员都没有意识到对象仍然有悬空引用,并且没有收集垃圾,导致内存泄漏.

通常情况下,事件在以后注册(+=但)但未注册时,以及访问非托管代码(使用pInvokes或使用底层系统资源的对象,如文件系统或数据库连接)并且未正确处理资源时.

  • GC比引用计数复杂得多,但除此之外.C/C++中的内存泄漏是"未释放但不再引用的内容".Java/.NET中的内存泄漏是"我们仍在引用但不应该引用的东西".当然,.NET类型的泄漏仍然可以在C/C++中发生,因此在.NET中发生内存泄漏的可能性要小一些,但仍然有可能. (41认同)

Joe*_*orn 43

这里已经有了一些很好的答案,但我想再谈一点.让我们再仔细看看你的具体问题:


我的理解是框架本身是用C++编写的,C++容易受到内存泄漏的影响.

  • 底层框架是如此精心编写的,它绝对没有任何内部内存泄漏的可能性?
  • 框架代码中是否存在自我管理甚至可以解决其自身内存泄漏的问题?
  • 答案是我没有考虑过的其他问题吗?

这里的关键是要区分你的代码和他们的代码..Net框架(以及Java,Go,python和其他垃圾收集语言)承诺,如果你依赖他们的代码,你的代码就不会泄漏内存......至少在传统意义上.您可能会发现自己处于某些对象没有按预期释放的情况,但这些情况与传统的内存泄漏略有不同,因为程序中的对象仍然可以访问.

你很困惑,因为你正确地理解这与说你创建的任何程序根本不可能有传统的内存泄漏是不一样的.他们的代码中仍然可能存在泄漏内存的错误.

所以现在你必须问自己:你宁愿相信你的代码还是他们的代码?请记住,他们的代码不仅仅是由原始开发人员进行测试(就像你的一样,对吗?),它也是由数千(可能是数百万)其他程序员(如自己)日常使用而战斗的.任何重大的内存泄漏问题都将是首先发现并纠正的问题.再说一遍,我不是说这是不可能的.信任他们的代码通常比自己的代码更好...至少在这方面.

因此,这里的正确答案是它是您第一个建议的变体:

底层框架是如此精心编写的,它绝对没有任何内部内存泄漏的可能性?

这不是没有可能,但它比自己管理它更安全.我当然不知道框架中有任何已知的泄漏.

  • Eric Lippert应该阅读这整个问题(希望在这里获得虚荣搜索). (2认同)

Mit*_*ers 15

在查看Microsoft文档(特别是" 识别CLR中的内存泄漏 ")之后,Microsoft确实发表声明,只要您没有在应用程序中实现不安全的代码,就不会发生内存泄漏

现在,他们还指出了感知内存泄漏的概念,或者如评论中指出的"资源泄漏",即使用具有延迟引用且未正确处理的对象.IO对象,数据集,GUI元素等可能会发生这种情况.在使用.NET时,它通常等同于"内存泄漏",但它们不是传统意义上的泄漏.


Ste*_*dit 12

由于垃圾收集,您不能有常规的内存泄漏(除了特殊情况,如不安全的代码和P/Invoke).但是,你当然可以无意中保持一个永远存在的引用,这有效地泄漏了内存.

编辑

到目前为止,我见过的最好的例子是事件处理程序+ =错误.

编辑

请参阅下文,了解错误的解释,以及与真正的泄漏相对应的条件,而不是几乎真正的泄漏.