.net垃圾回收学习【Back to Basics: Memory leaks in managed systems】【翻译&&学习】
2011-08-27 17:24
801 查看
From: http://blogs.msdn.com/b/abhinaba/archive/2010/01/05/back-to-basics-memory-leaks-in-managed-systems.aspx
有些人问他的Managed application为什么会内存一直在不停的增加,而且这很明显的是内存泄漏的标志,这些人都持有这个观点he is using .net and hence there should surely be no leaks。其他一些人也持有类似的观点。
然而这个观点是不正确的,可以通过以下两篇文章了解GC的工作机制:
http://blogs.msdn.com/abhinaba/archive/2009/01/20/back-to-basics-why-use-garbage-collection.aspx.
http://blogs.msdn.com/abhinaba/archive/2009/01/25/back-to-basic-series-on-dynamic-memory-management.aspx
需要注意的是: GC只会移除那些不再使用的对象,不幸运的,很容易写出来引用没有完全清除掉的代码。
示例1: event handling( discussed in more detail here)
考虑如下代码:
在这个例子中, 当强制执行GC的GC.collect的时候,并没有任何引用指向了sink对象(明确的将sink对象设置为NULL),然而,即使是这样,Sink仍然不会被回收。原因是sink正被当作一个event的Handler来使用,因此Src对象持有对sink的引用(这样当someEvent触发的时候,他能够调用sink.EventHandler)并且组织了它被回收。
示例2: Mutating objects in collection(discussed here)
这里有更深入的示例. 两年前看到一个讨论是当对象被放到一个Dictionary中,然后被取出来,使用,丢掉,现在获取的方式是通过Object key.示例如下:
创建一个对象并且放入到Dictionary
通过Object Key获取对象并使用。
调用Object上的方法。
随后再次通过key获取Object并且移除他。
现在对象并不是不可变的了,在使用对象的过程中,修改了对象的某个字段,而这个被修改的字段是用来计算对象的Hash Code的。这意味着在移除对象的过程中并没有找到对象而对象一直存在在Dictionary中。 你知道当修改一个对象的用于计算GetHashCode的字段为什么会导致将对象从Dictonary中移除会失败么?看这里:http://blogs.msdn.com/abhinaba/archive/2007/10/18/mutable-objects-and-hashcode.aspx
还有更多的的例子。
现在我们得出来的结论是:在托管的内存管理中,内存泄漏也是很普遍的情况。通常出现这种情况的原因是恰巧有些应当被清除掉的引用没有被明确的清楚掉,当GC找到这些对象的时候,发现这些对象仍然被其他对象引用,所以不会回收这些对象。
有些人问他的Managed application为什么会内存一直在不停的增加,而且这很明显的是内存泄漏的标志,这些人都持有这个观点he is using .net and hence there should surely be no leaks。其他一些人也持有类似的观点。
然而这个观点是不正确的,可以通过以下两篇文章了解GC的工作机制:
http://blogs.msdn.com/abhinaba/archive/2009/01/20/back-to-basics-why-use-garbage-collection.aspx.
http://blogs.msdn.com/abhinaba/archive/2009/01/25/back-to-basic-series-on-dynamic-memory-management.aspx
需要注意的是: GC只会移除那些不再使用的对象,不幸运的,很容易写出来引用没有完全清除掉的代码。
示例1: event handling( discussed in more detail here)
考虑如下代码:
EventSink sink = new EventSink();
EventSource src = new EventSource();
src.SomeEvent += sink.EventHandler;
src.DoWork();
sink = null;
// Force collection
GC.Collect();
GC.WaitForPendingFinalizers();
在这个例子中, 当强制执行GC的GC.collect的时候,并没有任何引用指向了sink对象(明确的将sink对象设置为NULL),然而,即使是这样,Sink仍然不会被回收。原因是sink正被当作一个event的Handler来使用,因此Src对象持有对sink的引用(这样当someEvent触发的时候,他能够调用sink.EventHandler)并且组织了它被回收。
示例2: Mutating objects in collection(discussed here)
这里有更深入的示例. 两年前看到一个讨论是当对象被放到一个Dictionary中,然后被取出来,使用,丢掉,现在获取的方式是通过Object key.示例如下:
创建一个对象并且放入到Dictionary
通过Object Key获取对象并使用。
调用Object上的方法。
随后再次通过key获取Object并且移除他。
现在对象并不是不可变的了,在使用对象的过程中,修改了对象的某个字段,而这个被修改的字段是用来计算对象的Hash Code的。这意味着在移除对象的过程中并没有找到对象而对象一直存在在Dictionary中。 你知道当修改一个对象的用于计算GetHashCode的字段为什么会导致将对象从Dictonary中移除会失败么?看这里:http://blogs.msdn.com/abhinaba/archive/2007/10/18/mutable-objects-and-hashcode.aspx
还有更多的的例子。
现在我们得出来的结论是:在托管的内存管理中,内存泄漏也是很普遍的情况。通常出现这种情况的原因是恰巧有些应当被清除掉的引用没有被明确的清楚掉,当GC找到这些对象的时候,发现这些对象仍然被其他对象引用,所以不会回收这些对象。
相关文章推荐
- .net垃圾回收学习[Best Practices No 5: Detecting .NET application memory leaks][翻译&&学习]]
- .net垃圾回收学习【Back to basics: Why use garbage collection】【翻译&&学习】
- .net 垃圾回收学习[Back To Basics: How does the GC find object references][翻译&&学习]
- .net垃圾回收学习【NET Best Practice No: 1:- Detecting High Memory consuming functions in .NET code】【翻译&&学习】
- .net垃圾回收学习[Back to Bascis: Generational garbage collection][翻译&&学习]
- .net垃圾回收学习【NET Best Practice No: 3:- Using performance counters to gather performance data】【翻译&&学习】
- .net 垃圾回收学习【Memory leak via event handlers】【翻译&&学习】
- .net 垃圾回收学习[http://www.codeproject.com/KB/dotnet/idisposable.aspx][翻译&&学习][2]
- .net 垃圾回收学习[http://www.codeproject.com/KB/dotnet/idisposable.aspx][翻译&&学习][2]
- .net 垃圾回收学习[NET 2.0 Performance Guidelines - String Operations]【翻译&&学习】
- .net 垃圾回收学习[How To: Use CLR Profiler][翻译&&学习]
- .net 垃圾回收学习[How To: Use CLR Profiler][翻译&&学习]【3】
- .net 垃圾回收学习[http://www.codeproject.com/KB/dotnet/idisposable.aspx][翻译&&学习][2]
- .net垃圾回收学习【.NET Best Practice No: 2:- Improve garbage collector performance using finalize/dispose pattern】【翻译&&学习】
- Garbage Collection : Automatic Memory Management in the Microsoft .NET Framework 垃圾回收:在微软NET框架自动内存管理(一)
- How to detect and avoid memory and resources leaks in .NET applications()
- How to detect and avoid memory and resources leaks in .NET applications
- .net垃圾回收学习【IDisposable: What Your Mother Never Told You About Resource Deallocation】[翻译&学习]
- .net垃圾回收学习[NET 2.0 Performance Guidelines - Garbage Collection][翻译加学习]
- How to detect and avoid memory and resources leaks in .NET applications