这源于我最近在事件和内存管理方面的一些帖子。我正在提出一个新问题,因为我不认为我使用的软件与整体问题有任何关系,而我正在尝试更多地了解如何正确管理事物。这是ASP.NET。
过去几天我一直在努力了解Dispose / Finalize的需求,并相信我已经到了一个阶段,我应该/不应该实现Dispose / Finalize 。 '如果我有成员实现IDisposable,在我的处理方法中明确调用他们的处理'似乎是我的理解。所以,现在我想的可能是我对物体生命周期的理解以及对于什么是错误的理解!
我没有想出一些示例代码,我认为这些代码将说明我的观点,我将尽可能地描述实际的代码,看看是否有人可以通过它来说话。
所以,我有一个存储库类,其中有一个我创建存储库时创建的DataContext。我实现了IDisposable,当我的调用对象完成后,我在我的存储库上调用Dispose并显式调用DataContext.Dispose()。现在,此类的一个方法创建并返回一个返回到我的前端的对象列表。
前端 - >控制器 - >存储库 - >控制器 - >前端。
(使用Redgate Memory Profiler,我会在首次加载页面时拍摄我的软件的快照)。我的前端在页面加载时创建一个控制器对象,然后向存储库发出请求,发回一个项目列表。当页面加载完毕后,我在控制器上调用Dispose,然后在上下文中调用dispose。在我看来,这应该意味着我的连接已关闭,并且我没有控制器类的实例。如果我然后刷新页面,它会跳转到控制器类的两个“实时”实例。如果我查看对象保留图,我在调用列表时创建的对象最终会被Linq看起来。
除了控制器/存储库之外,如果我在某处创建了一个对象列表,或者我创建了一个对象并将其返回到某处,我可以安全地假设.NET最终会为我清理一下或者是否存在最佳实践? “实时”实例告诉我,这些仍然存在于内存和活动对象中,RMP显然迫使GC没有任何意义吗?
答案 0 :(得分:1)
如果对象不再被root,它们最终将完全从内存中删除,但调用Dispose
不会立即将对象从内存中完全删除。 Dispose
仅允许您清理非托管资源以及需要尽快释放的资源。
换句话说:您的连接应该关闭,但内存中仍然会有一个“处置”的DataContext实例。
您可能希望read this article关于.NET垃圾回收。
答案 1 :(得分:1)
我对你的问题的回答由两部分组成:
作为应用程序开发人员,您永远不需要自己执行GC。这取决于.NET。在Dispose()方法中,您只需要放弃或释放已获取的资源,但不需要调用任何方法来显式执行垃圾收集。如果你这样做,充其量,当它完成时是不确定的。
当您的控制器将列表返回到前端时,请记住前端不需要知道您的服务器端(后端)技术是什么。它可能是C#,Java,PHP,你明白了。后端返回前端的响应只是HTTP响应,符合HTTP协议。因此,一旦响应被构造并返回到前端,控制器方法就会超出范围,该范围内的对象将被收集垃圾。在这种情况下,您不必担心内存泄漏。