

























2013-03-10 17:29 拖鞋不脱 阅读(2448) 评论() 收藏 举报
在.Net 中,内存的管理和释放都由GC(Garbage Collection)管控,一般不需太多关注。但依然可能有内存泄漏(隐式内存泄漏)的情况出现,即一些早应结束它的生命周期的对象,直到程序结束才会被释放。具体到Silverlight中的表现,就是Silverlight所在浏览器进程占用的内存不断增长,直到崩溃或关闭浏览器。
In .Net world, GC manages the memory. So we normally don’t need too much concern over the memory mangement. But there still can be memory leak issue: some instances dont’t release memory until the end of application, while they have ended their life circle long before. Specific to the Silverlight situation, is the memory of the browser process who takes the silverlight continues to grow, until the collapsing or the closing of the browser.
对象是否释放是由GC管理的,什么样的对象会被GC释放?已经不再被应用程序的Root或者别的对象所引用的对象。而内存泄漏,就出现在那些从业务角度来看,应该已经不被引用,而实际仍被其他对象所引用的对象上。
假设有A、B两个对象,A引用了B,那么当A没有释放的时候,B也就不会被释放。如果A又恰巧是程序的Root或被Root所引用(如全局静态变量),那么B就很不幸的在整个程序的生命周期中都不会被释放。
这种情况一般不会发生,因为如果某个对象和Root产生了关联,往往是我们有意识的将它塑造成一个全局的、希望在整个程序的生命周期都存在的对象,这就不存在内存泄漏的问题。而意外往往就发生在我们无意识的地方——事件。
假设A有事件EventA,我们在B中处理了A的EventA,往往会写成这样:A.EventA += B.HandleEventA; 这时也许你不会意识到我们已经在A中添加了B的引用,因为在A中我们需要把B添加到它的监听者集合中,以便每次触发EventA的时候,都调用B的HandleEventA来处理这个事件。如果我们事后没有及时的通过A.EventA –= B.HandleEventA; 来将B从A的监听者集合中移除,那么B就会成为导致内存泄漏的一个元凶。
所以,全局事件监听、静态变量的事件监听,都可能在无意间消耗了我们大量的内存。
看到上面一节,也许你已经意识到在自己的应用中有这样的问题并准备着手解决。不过我依然想先提供两种检测内存泄漏的简单方案:
以上两种方法可以用来判断是否存在内存泄漏的问题,简单易行,而且结合对内存泄漏原因的理解,如果代码结构良好,逻辑清晰的话,应该很容易找到是哪里出现了不恰当的引用,从而解决内存泄漏的问题。但如果逻辑本身比较复杂,引用交织纷繁的话,我推荐利用Windbg进行更详细系统的排查,具体内容参见:http://blogs.msdn.com/b/delay/archive/2009/03/11/where-s-your-leak-at-using-windbg-sos-and-gcroot-to-diagnose-a-net-memory-leak.aspx
如同内存泄漏问题的检测有多种手段,内存泄漏问题的解决依然有多种方式:
所以我们要注意在Silverlight乃至.Net开发中的内存泄漏问题,尤其是全局事件或静态变量事件的处理,通过内存监控、析构函数跟踪等方法确定内存泄漏的发生,并通过Weak Event Pattern来规避此类问题的发生。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。