.NET 资源泄漏问题
开发人员可能会因 .NET 中无意的资源泄漏而陷入困境。 我认为将它们集中在一处会很有用。
请为每个项目添加一个答案,以便最佳答案被投票:)
There are several ways that developers can get caught out by unintentional resource leaks in .NET. I thought it would be useful to gather them in one place.
Please add yours with one answer per item, so the best get voted up :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(17)
无法删除事件处理程序。
注册事件应该与取消注册配对:
有一个系统示例,在 代码项目。
Failure to remove Event Handlers.
Registering for an event should be paired with un-registering:
There is an example of a system where this happened on CodeProject.
P/调用非托管代码,并且不清理它们,或者不实现 IDisposable 来清理它们。
P/Invoking to unmanaged code, and not cleaning them up, or not implementing IDisposable to get them cleaned up.
不使用
使用
。Not using
Using
.保持数据库连接打开。
Leaving database connections open.
未能实现 Dispose,因此未处理子对象。
Failure to implement Dispose and so not disposing child objects.
WCF 客户端对象的执行方式与其他 IDisposable 对象不同。 如果操作处于故障状态,则必须中止 WCF 服务的客户端,否则它将保持连接打开状态。 这通常是通过艰难的方式学到的。
WCF client objects do not perform like other IDisposable objects. The client of a WCF service must be aborted if the operation is in a faulted state or else it will keep the connection open. This is usually learned the hard way.
使用 Office API 时的几乎所有内容。 由于它们都是 COM 对象,因此必须将它们释放。 如果您想使用事件处理程序,您还必须保留对它们的类引用,否则它们会丢失引用。 很多情况下,你甚至需要手动调用GC来清理对象
Pretty much everything when using the Office APIs. Since they are all COM objects, they must be disposed. You also have to keep a class reference to them if you want to use event handlers, otherwise they lose their reference. In a lot of cases, you even have to manually call the GC in order to clean up the objects
使用 WeakReference 可能会导致微妙的泄漏,其中 WeakReference 所持有的对象被清理,因为它没有强引用,但 WeakReference 本身却没有,因为您保留了对它的强引用。
如果您有类似弱引用列表或字典之类的东西但从未修剪过,则可能会遇到这种情况。 即使目标已被收集,您最终也会泄漏 WeakReference 对象。
Using a WeakReference can lead to the subtle leak where the object held by the WeakReference is cleaned up because it has no strong references but the WeakReference itself is not because you keep a strong reference to it.
You can run into this if you have something like a List or Dictionary of WeakReferences which you never prune. You'll end up leaking WeakReference objects even after the target has been collected.
容易内存泄漏:在List类型的类中创建一个静态字段。 将项目添加到列表。 它们永远不会被垃圾收集,因此除非您记得在使用完它们后手动删除它们,否则内存将永久占用。
Easy memory leak: make a static field in a class of type List. Add items to List. They'll never get garbage collected, so unless you remember to manually remove your items when you're done with them, the memory is permenantly tied up.
无法调用 System.Windows.Window 对象上的“Close”方法。
确保对 System.Windows.Window 对象的所有托管资源进行垃圾收集的唯一方法是调用 Window 对象的“Close()”方法。 调用 Dispose 或将对象引用设置为 null 不会销毁该对象。
Failure to call the 'Close' method on the System.Windows.Window object.
The only way to ensure that all managed resources for a System.Windows.Window object are garbage collected is to call the 'Close()' method on the Window object. Calling Dispose or setting the object reference to null will not destroy the object.
如果将托管内存视为“资源”,则未能取消事件处理程序是内存泄漏(以及各种其他更严重的错误)的常见来源。
If you count managed memory as a "resource" - failing to unhook event handlers is a common source of memory leaks (and various other more serious bugs).
在启动代码之外填充的基于静态列表、字典和集合的资源。
如果您使用字典作为全局缓存而不是基于 LRU 的适当缓存,则可能会发生这种情况。
任何静态都需要格外小心!
Static Lists, Dictionaries and collection based resources that are populated outside of start-up code.
This can happen if you have a Dictionary you use as a global cache instead of a proper LRU based cache.
Anything static requires a lot of extra caution!
模拟令牌句柄保持打开状态。
Impersonation token handles left open.
无法在 .NET Compact Framework 上处理任何与绘图相关的对象(图形、字体、SolidBrush、笔等)。 当您不想要时,这可能会导致一些严重的内存泄漏(移动设备=有限的内存)。
Failure to dispose any Drawing related objects (Graphics, Font, SolidBrush, Pen, etc.) on the .NET Compact Framework. This can cause some serious memory leaks when you don't want (mobile device = limited memory).
WPF 资源字典泄漏。 一些有用的链接:
WPF resource dictionary leaks. Some helpful links:
错误配置 Spring.NET 来创建应该是单例的多个实例。
Misconfiguring Spring.NET to create multiple instances of something that should be a singleton.
无法在 定时器
Failed to call Dispose() on Timer