常见的内存泄露演示
作者使用了一个Forma,每一个按钮都会打开一个子form。按常理,当子form被关闭时,我们都希望它所占有的资源被自动释放。但在这里,作者将在每一个子form中演示一种泄露的情况。
Static references
最明显的,如果一个对象被静态字段(field)引用,它永远都不会被释放。这种情况常见于单键模式,因为它们往往都市静态的,要不就是长时间驻留的。
这些直接引用往往都是显而易见的,但真正危险的都是那些间接引用。因此你需要格外注意引用串。一个有效的方法就是查看这个串的根,如果这个根式静态的,那整个串上的引用都无法被释放。
如上图,如果Object1是静态的或者长驻留的,那么这条引用串上的对象都不被释放。危险的是,串很长时就很难意识到它的根是静态类型的。比如,如果仅仅注意了一级深度,那么当Object2消失的时候,Object3和Object4就应该被释放,当你很可能忽视了Object1的存在。
建议是慎用静态类型,尽可能的不用,否则请格外注意其或其他单键对象的内存驻留时间。
一种具体的风险就是静态事件,将在事件泄露演示中阐述。
事件或"lapsed listener"
子form订阅了main form的事件,以便在main form的通透度(opacity)变化时得到通知。
问题由此产生:OpacityChanged事件创建了一个由main form到子form的引用:
作者在另外一篇文章中讨论了 事件和引用的关系 ,这里只给出了演示图,和jetTrace截图:
作者使用了一个Forma,每一个按钮都会打开一个子form。按常理,当子form被关闭时,我们都希望它所占有的资源被自动释放。但在这里,作者将在每一个子form中演示一种泄露的情况。
Static references
最明显的,如果一个对象被静态字段(field)引用,它永远都不会被释放。这种情况常见于单键模式,因为它们往往都市静态的,要不就是长时间驻留的。
这些直接引用往往都是显而易见的,但真正危险的都是那些间接引用。因此你需要格外注意引用串。一个有效的方法就是查看这个串的根,如果这个根式静态的,那整个串上的引用都无法被释放。
如上图,如果Object1是静态的或者长驻留的,那么这条引用串上的对象都不被释放。危险的是,串很长时就很难意识到它的根是静态类型的。比如,如果仅仅注意了一级深度,那么当Object2消失的时候,Object3和Object4就应该被释放,当你很可能忽视了Object1的存在。
建议是慎用静态类型,尽可能的不用,否则请格外注意其或其他单键对象的内存驻留时间。
一种具体的风险就是静态事件,将在事件泄露演示中阐述。
事件或"lapsed listener"
子form订阅了main form的事件,以便在main form的通透度(opacity)变化时得到通知。
mainForm.OpacityChanged += mainForm_OpacityChanged;
问题由此产生:OpacityChanged事件创建了一个由main form到子form的引用:
作者在另外一篇文章中讨论了 事件和引用的关系 ,这里只给出了演示图,和jetTrace截图:
How to detect and avoid memory and resources leaks in .NET applications 摘译2