如何在C#/ .NET中创建内存泄漏
可能重复:
托管代码中是否可能存在内存泄漏? (特别是C#3.0)
C#中的内存泄漏
昨天有一个类似的问题,但是对于Java,所以我很感兴趣 – 在C#/ .NET中创建内存泄漏需要什么(不使用不安全的)?
静态事件; 死,因为他们永远不会超出范围。
static event EventHandler Evil; for(int i = 0 ; i < 1000000 ; i++) Evil += delegate {};
匿名方法在这里只是一个很好的方法,但很好,因为它们也是取消订阅的猪,除非你将副本带入变量/字段并订阅它 。
从技术上讲,这实际上并没有“泄露”,因为您仍然可以通过Evil.GetInvocationList()
访问它们 - 但是,当与常规对象一起使用时,这可能会导致意外的对象生命周期,即
MyHeavyObject obj = ... ... SomeType.SomeStaticEvent += obj.SomeMethod;
现在obj
的对象永远存在。 这足以满足感知泄漏的 IMO,并且“我的应用程序死于可怕的死亡”对我来说已经足够了; p
当一个对象订阅一个事件时,暴露事件的对象会维护对订阅者的引用(实际上,事件, MultiCastDelegate
最初会执行,但它会继续)。 如果最后一次引用(除了由event
维护的引用)超出范围,此引用将阻止订户进行GC。
另外两个答案完全落后并且不正确。 这在一个简单的例子中显示有点棘手,并且通常在较大的项目中看到,但是请记住, MultiCastDelegate
( event
)维护了对订阅者的引用,您应该能够思考它。
编辑:正如Marc在他的回复中提到的,你可以在技术上通过GetInvocationList()
方法获得对“泄露”对象的引用,但是你的代码不太可能使用它,并且当你使用OutOfMemoryExcetion
崩溃时无关紧要。
直接内存访问是从安全的托管代码中抽象出来的。 必须在某处调用不安全的代码,以便在您编写的代码或第三方资源(可能在FCL中)内存泄漏错误导致内存泄漏。