.net 垃圾回收学习【Memory leak via event handlers】【翻译&&学习】
2011-08-27 18:07
447 查看
From: http://blogs.msdn.com/b/abhinaba/archive/2009/05/05/memory-leak-via-event-handlers.aspx
分享一下我们的客户最近比较感兴趣的内存溢出的问题。
在以上的代码中假如你为EventSink添加一个Finaizer方法的话,然后在Finalizer方法中添加一个端点或者控制台输出的话,你会发现它永远不会触发,即使你将Sink设置为NULL。原因是在第三行我们将sink添加到了Source的Invoke list上了。所以即使sink被设置为NULL,最初的对象依然是可以从Src reachable的。
+=操作执行的时候将sink添加到了对象的触发列表中,当把sink设置为NULL的时候,Sink的老对象仍然在内存中,导致内存不停的增大,最终在某个点会导致崩溃。
修复的方法是确保移除了sink.
上面的代码只是一个示例,显然你不应该在多处进行Event的Add,remove操作。确保EventSink实现了IDisposable模式,将+=,-=操作封装在ctor/dispose中。
分享一下我们的客户最近比较感兴趣的内存溢出的问题。
The short version
问题的核心是他们有Event sinks和Sources。 Event sinks被正确的释放,然而,在释放的过程中他们忘记了从触发事件的source中移除event sink.所以,事实上,已经被释放掉的sinks仍然可以从event source被reachable。所以GC不会释放Event sinks并且会导致泄漏的对象。Now the not-so-long version
考虑如下代码,这里有EventSource和EventSink对象,EventSource对外公开SomeEvent事件,Sink可以订阅此事件。EventSink sink = new EventSink();
EventSource src = new EventSource();
src.SomeEvent += sink.EventHandler;
src.DoWork();
sink = null;
// Force collection
GC.Collect();
GC.WaitForPendingFinalizers();
在以上的代码中假如你为EventSink添加一个Finaizer方法的话,然后在Finalizer方法中添加一个端点或者控制台输出的话,你会发现它永远不会触发,即使你将Sink设置为NULL。原因是在第三行我们将sink添加到了Source的Invoke list上了。所以即使sink被设置为NULL,最初的对象依然是可以从Src reachable的。
+=操作执行的时候将sink添加到了对象的触发列表中,当把sink设置为NULL的时候,Sink的老对象仍然在内存中,导致内存不停的增大,最终在某个点会导致崩溃。
修复的方法是确保移除了sink.
EventSink sink = new EventSink();
EventSource src = new EventSource();
src.SomeEvent += sink.EventHandler;
src.DoWork();
src.SomeEvent -= sink.EventHandler;
sink = null;
上面的代码只是一个示例,显然你不应该在多处进行Event的Add,remove操作。确保EventSink实现了IDisposable模式,将+=,-=操作封装在ctor/dispose中。
相关文章推荐
- .net垃圾回收学习[Back to Bascis: Generational garbage collection][翻译&&学习]
- .net垃圾回收学习【NET Best Practice No: 3:- Using performance counters to gather performance data】【翻译&&学习】
- .net 垃圾回收学习[http://www.codeproject.com/KB/dotnet/idisposable.aspx][翻译&&学习][2]
- .net 垃圾回收学习[http://www.codeproject.com/KB/dotnet/idisposable.aspx][翻译&&学习][2]
- .net垃圾回收学习【NET Best Practice No: 1:- Detecting High Memory consuming functions in .NET code】【翻译&&学习】
- .net垃圾回收学习【.NET Best Practice No: 2:- Improve garbage collector performance using finalize/dispose pattern】【翻译&&学习】
- .net 垃圾回收学习[How To: Use CLR Profiler][翻译&&学习]【3】
- .net 垃圾回收学习[http://www.codeproject.com/KB/dotnet/idisposable.aspx][翻译&&学习][2]
- .net 垃圾回收学习[How To: Use CLR Profiler][翻译&&学习]
- .net 垃圾回收学习[NET 2.0 Performance Guidelines - String Operations]【翻译&&学习】
- .net垃圾回收学习【Back to Basics: Memory leaks in managed systems】【翻译&&学习】
- .net垃圾回收学习[Best Practices No 5: Detecting .NET application memory leaks][翻译&&学习]]
- .net垃圾回收学习【IDisposable: What Your Mother Never Told You About Resource Deallocation】[翻译&学习]
- .net垃圾回收学习[NET 2.0 Performance Guidelines - Garbage Collection][翻译加学习]【2】
- .net垃圾回收学习【C# 中的Stack和Heap】【翻译&&学习】
- .net 垃圾回收学习[How To: Use CLR Profiler][翻译&&学习]【2】
- .net 垃圾回收学习[Back To Basics: How does the GC find object references][翻译&&学习]
- .net垃圾回收学习[NET 2.0 Performance Guidelines - Garbage Collection][翻译加学习]
- .net垃圾回收学习【Back to basics: Why use garbage collection】【翻译&&学习】
- 【转】.NET深入学习笔记(3):垃圾回收与内存管理