我如何说服我的同事没有实现IDisposable的一切? [英] How do I convince my colleagues not to implement IDisposable on everything?

查看:169
本文介绍了我如何说服我的同事没有实现IDisposable的一切?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我工作在一个项目中,有一个巨大的物体的数量被实例化由少数几个类保存在内存中应用程序的生命周期。有很多的内存泄漏而引起的与OutOfMemoryExceptions,现在又被抛出每一个。这似乎是后实例化对象之前超出范围,他们不会被垃圾收集。

我已经分离出了问题是大多是关于连接到那些从来没有脱离长期生活的对象,该事件处理程序,从而使长期生活的对象仍然有参考了范围的对象,然后永远不会被垃圾收集。

这已经提出了我的同事的解决方案如下:实现IDisposable的所有类,全线和Dispose方法,空所有的在你的对象引用,并从您连接到所有的事件分离

我相信这是一个非常非常糟糕的主意。首先是因为它的'矫枉过正',因为这个问题可以通过固定的几个问题的领域被大部分解决,其次是因为IDisposable接口的目的是为了释放任何的非托管的资源,你的对象的控制,不会因为你不信任垃圾收集器。到目前为止,我的论点都置若罔闻。我怎样才能说服他们,这是徒劳的?

解决方案

巧合的是我刚刚张贴此评论别处:

  

这是引用一个对象是   不正确地保留仍然是一个   资源泄漏。这就是为什么GC方案   还会有泄漏,通常是由于   观察者模式 - 观察者   名单上,而不是观察到的和   永远不会被带下了。最终,一个   删除是需要每添加,只是   作为删除是需要每。   一模一样的编程错误,   引起完全相同的问题。一个   资源是真的只是一对   具有的功能被称为   相同的次数与   相应的参数,以及   资源泄漏是发生了什么时,   你不能做到这一点。

和你说:

  

目的的IDisposable 是释放任何   非托管资源的对象   控制

现在,在 + = = - 上的事件运营商有效的一对函数,你有调用相等数量的具有相应参数倍(事件/处理程序对作为相应的参数)。

因此​​,他们构成的的资源。的而且因为他们没有处理(或管理),由GC对你来说,它可以是把它们看作是另一种非托管资源的有益。由于乔恩斯基特指出,在评论中,非托管通常有特定的含义,但在的IDisposable 的方面,我认为这是有帮助的,以扩大它包括任何资源一样,有被推倒后,已经建成。

所以,事件剥离是一个很好的候选人与的IDisposable 处理。

当然,你需要调用处置的地方,而你并不需要实现它的每一个对象(只是那些需要管理事件的关系)上。

另外,要记住,如果一对对象是由一个事件连接,和你扔漂流,被丢失在了其他东西,他们都提到,他们不会让对方活着。 GC不使用引用计数。一旦一个对象(或对象岛)不可达,它是由为收集。

您只需要担心的对象入伍,与上活得长的对象事件的事件处理程序。例如一个静态事件,如 AppDomain.UnhandledException 或事件的应用程序的主窗口。

I work on a project where there is a huge number of objects being instanced by a few classes that stay in memory for the lifetime of the application. There are a lot of memory leaks being caused with OutOfMemoryExceptions being thrown every now and again. It seems like after the instantiated objects ago out of scope, they are not being garbage collected.

I have isolated the problem to being mostly about the event handlers that are attached to the long-living object that are never detached, thus causing the long-living object to still have a reference to the out of scope objects, which then will never be garbage collected.

The solution that has been proposed by my colleagues is as follows: Implement IDisposable on all classes, across the board and in the Dispose method, null all the references in your objects and detach from all event that you attached to.

I believe this is a really really bad idea. Firstly because it's 'overkill' since the problem can be mostly solved by fixing a few problem areas and secondly because the purpose of IDisposable is to release any unmanaged resources your objects control, not because you don't trust the garbage collector. So far my arguments have fallen on deaf ears. How can I convince them that this is futile?

解决方案

By coincidence I just posted this comment elsewhere:

An reference to an object being incorrectly retained is still a resource leak. This is why GC programs can still have leaks, usually due to the Observer pattern - the observer is on a list instead the observable and never gets taken off it. Ultimately, a remove is needed for every add, just as a delete is needed for every new. Exactly the same programming error, causing exactly the same problem. A "resource" is a really just a pair of functions that have to be called an equal number of times with corresponding arguments, and a "resource leak" is what happens when you fail to do that.

And you say:

the purpose of IDisposable is to release any Unmanaged resources your objects controls

Now, the += and -= operators on an event are effectively a pair of functions that you have to call an equal number of times with corresponding arguments (the event/handler pair being the corresponding arguments).

Therefore they constitute a resource. And as they are not dealt with (or "managed") by the GC for you, it can be helpful to think of them as just another kind of unmanaged resource. As Jon Skeet points out in the comments, unmanaged usually has a specific meaning, but in the context of IDisposable I think it's helpful to broaden it to include anything resource-like that has to be "torn down" after it has been "built up".

So event detaching is a very good candidate for handling with IDisposable.

Of course, you need to call Dispose somewhere, and you don't need to implement it on every single object (just those with event relationships that need management).

Also, bear in mind that if a pair of objects are connected by an event, and you "cast them adrift", by losing all references to them in all other objects, they don't keep each other alive. GC doesn't use reference counting. Once an object (or island of objects) is unreachable, it is up for being collected.

You only have to worry about objects enlisted as event handlers with events on objects that live a long time. e.g. a static event such as AppDomain.UnhandledException, or events on your application's main window.

这篇关于我如何说服我的同事没有实现IDisposable的一切?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆