Otá*_*cio 21
在IDisposable对象上调用Dispose或使用该using子句.这应该照顾我能想到的大部分泄漏.
正如ocdecio所提到的,请确保在Idisposable对象上调用Dispose,并记住在完成对象时删除事件处理程序.在构建使用非托管资源的类时,请务必实现Idisposable,以便用户知道有一些关键资源需要处理.
此外,即使垃圾收集为您做了相当多的工作,您也应该摆脱对您已完成的对象的引用.否则他们仍然会有一个根,他们将不会被GC.
在这些情况下,不要低估工具的帮助性..NET内存分析器现在相当成熟和强大,如果你有一个复杂的应用程序,你认为应该释放的对象仍被其他东西作为参考,那么精确定位该引用的能力是非常宝贵的.
我刚刚完成了内存泄漏,其中一个WPF标签页托管了一个Windows窗体控件(因为这些标签保存了大量数据,您可以随意打开和关闭它们,只需等待GC清除内存关闭不是一个选项).我使用YourKit分析器在打开选项卡之前拍摄内存快照,打开选项卡,再次关闭它并拍摄另一个快照.在探查器内部,您可以在视觉上比较两个快照,并查看哪些对象在该过程中幸存,并将其引用关注回GC根目录.我没有其他剖析器的经验,但我知道如果YourKit无法满足您的需求,那里有一些.
编辑添加:
好吧,这不是避免内存泄漏,它正在修复它们.但是我会把它留在这里,因为我认为它是有用的信息,我认为没有足够的.NET开发人员知道这些工具.
内存泄漏是错误,所以一般来说 - 这个问题可以像"如何编写没有错误"一样回答?从长远来看 - 不可能没有bug,但你可以限制在发布的代码中使用它们的机会.
首先关注开发的代码质量并遵循其他人提到的指导原则.
除此之外 - 实现测试以查看内存是否泄漏 - 单元,并发,压力和负载测试最有帮助.通过检查指标(perf计数器)查看内存是否泄漏.您还可以记录对象创建和破坏,并在测试结束时分析日志.