2010-06-01 234 views
1

这源自我近期在事件和内存管理方面所做的最近几篇文章。我提出了一个新问题,因为我不认为我使用的软件与整体问题有任何关系,我想了解更多有关如何正确管理事情的信息。这是ASP.NET。对象关系

我一直在试着理解过去几天Dispose/Finalize的需求,并相信我已经到了一个阶段,我很满意何时应该/不应该实现Dispose /最终确定。 '如果我的成员实现了IDisposable,在我的dispose方法中显式调用它们的配置'似乎是我的理解。所以,现在我想,也许我对对象生命周期的理解,以及什么是错误的!

我不想拿出一些示例代码,我认为这些代码将说明我的观点,我将尽我所能地描述实际代码,并确定是否有人可以通过它来说服我。

所以,我有一个存储库类,其中我有一个DataContext,创建存储库时创建。我实现了IDisposable,当我的调用对象完成时,我在我的仓库上调用Dispose并显式调用DataContext.Dispose()。现在,这个类的一个方法创建并返回一个交给我前端的对象列表。

前端 - >控制器 - >存储库 - >控制器 - >前端。

(使用Redgate内存分析器,当第一次加载页面时,我拍摄了我的软件的快照)。我的前端在页面加载时创建一个控制器对象,然后向存储库发送一个请求,返回项目列表。当页面完成加载后,我在控制器上调用Dispose,然后调用Dispose来处理上下文。在我看来,这应该意味着我的连接已关闭,并且我没有控制器类的实例。如果我然后刷新页面,它将跳转到控制器类的两个'Live'实例。如果我看一下对象保留图,我在调用列表时创建的对象最终将被保持为看起来像Linq。如果我在某处创建一个对象列表,或者我创建了一个对象并将它返回到某处,我可以安全地假设.NET最终会为我清理一些东西,或者在那里最佳实践? '活'实例告诉我,这些仍然在记忆和活跃的对象,事实上,RMP显然强迫GC并不意味着什么?

+0

您能说清楚'主动'或'活'对象的含义吗?你的意思是还有一些参考可以从根访问吗?通常,未引用的对象会被清理得很好,尽管有些情况(特别是在注册事件处理程序时),您可以在其中留下根本无关的悬挂引用。委托链保持对注册类的引用存活,这通常会导致内存泄漏。 – 2010-06-01 22:06:08

+0

我的意思是RMP报告为Live实例。它显示自上次快照创建的实例,然后显示活动实例的数量。就我而言,我看到总共有两个活动实例增加了1个实例。 – Hammerstein 2010-06-02 02:13:03

回答

1

如果对象不再扎根,它们最终会从内存中完全移除,但调用Dispose不会导致对象立即从内存中完全移除。 Dispose仅允许您清理非托管资源以及需要尽快释放的资源。

换句话说:您的连接应该关闭,但内存中仍然会有一个“处置的”DataContext实例。

您可能想要关于.NET垃圾回收read this article

+0

感谢您的文章链接。我在Simple-Talk上发现了一些文章,他们都非常有帮助。 – Hammerstein 2010-06-02 02:11:48

1

我的回答你的问题由两个部分组成:

  1. 作为应用程序开发,你永远不会需要执行GC自己。这取决于.NET。在Dispose()方法中,只需要放弃或释放已获取的资源,但不需要调用任何明确执行垃圾收集的方法。如果你这样做,充其量,完成时是不确定的。

  2. 当您的控制器返回一个列表到前端时,请记住前端不需要对您的服务器端(后端)技术不知道什么。它可以是C#,Java,PHP,你明白了。后端返回到前端的响应只是一个HTTP响应,并且符合HTTP协议。因此,一旦响应被构造并返回到前端,控制器方法就会超出范围,该范围内的对象将启用垃圾收集。在这种情况下,您不必担心内存泄漏。