Uses of "using" in C#对using
功能的实用程序有一个很好的解释。
.Net有它的垃圾收集器。它如何处理缺乏dipose()?
特别是对于DB连接,语句和结果集,是否需要对每个连接使用using()?如果他们被遗忘而没有使用use(),dispose()和close()?
会发生什么更新:上下文是Web应用程序,因此可能有数千个并发用户,每个用户都有自己的连接/ stmt / rs,应用程序将永远不会关闭。
答案 0 :(得分:3)
由于using
是调用Dispose
的简写,您可以使用try / finally模仿它。所以真正的问题是什么不是完全不调用Dispose
的结果。
虽然C#具有垃圾收集功能,而最终大部分时间都会释放资源,但您希望在完成这些资源后立即发布关键资源。如果您使用using
或等效的try
/ finally
,资源将会快速发布。如果您让垃圾收集器为您释放资源,那么您的程序可能会在资源被限制的情况下被资源匮乏。 GC(即您的程序不再使用它们,但GC还没有发布它们)。此外,由于GC没有提供运行终结器的硬保证,因此在程序结束之前可能无法明确释放某些资源,这可能会导致其他进程资源不足。
答案 1 :(得分:1)
您不知道.net的垃圾收集器何时被调用并运行,因此当您不需要它时,它允许您自己完成。因此,当您的代码不再使用()时,它会使用using()中使用的dispose对象,而不是等待GC按照自己的计划运行。
如果您不使用数据库连接,那么GC将根据其实施的算法标准以自己的方式进行处理。扫描它可能为时已晚(就计算机时钟而言)。
垃圾收集器是一个后台线程,它不会每毫秒运行一次。它具有特定的时间表和自己的算法,使其在特定时间内工作。例如,一些GC算法会检查没有引用的对象,然后在GC运行时扫描这些对象。
答案 2 :(得分:1)
特别是对于DB连接,语句和结果集,是这样 每个人需要使用using()吗?如果他们离开会发生什么 没有using(),dispose()和close()?
实际上,内存泄漏的最坏后果是在重新启动PC之前保留一些内存。但是在这种情况下,可能最糟糕的后果是在重新启动应用程序之前泄漏内存。
如果内存增长增加到GC无法再清理的地方,实际上如果Small Object Heap的Gen 2溢出(大对象堆也可能溢出),它将抛出内存异常并关闭应用程序。
.Net有它的垃圾收集器。它是如何处理缺乏的 dipose()?
所有与标准数据库连接相关的类都已正确实现Dispose和Finalize方法。通常,这些类中存在非托管资源。非托管资源是资源(例如:文件处理程序,数据库连接处理程序等),这可能会导致更糟的内存泄漏,可能会在重新启动PC之前保留内存。然而,GC的最终确定很方便。如果你没有为这样的Disposable对象调用Dispose,垃圾收集器将执行Finalize方法(如果有一个〜析构函数)并清除非托管资源。
这就是为什么需要根据需要正确实现IDispose Pattern Dispose和Finalization的原因。只有在具有Unamanged资源的情况下才需要终结。
答案 3 :(得分:1)
未能及时Dispose
数据库对象的最可能后果是程序将要求数据库服务器代表它打开数据库连接,并承诺它将告诉服务器何时不再需要它们(即关闭它们),但可能会在不再需要它们之后将连接打开一段时间。此类行为可能会增加数据库服务器同时保持打开所需的连接数。根据服务器的不同,可能没有后果,或者额外的连接可能会影响性能,或者它们可能会导致某些连接请求被不必要地拒绝。
尽管.NET会尝试确保在放弃数据库对象时通知数据库服务器,但即使未调用Dispose
,使用数据库对象的代码通常也会知道它何时不再需要它们,早在.NET可以确定它们被放弃之前。另请注意,虽然某些与.NET数据库相关的库可能会在Dispose
之后保持连接打开一段时间(因此,如果代码再次需要数据库,它可以继续使用之前的连接),这些库可能会使用计时器来限制连接保持多长时间以期待进一步使用,而不是依赖于垃圾收集器(可能需要很长时间而不会注意到对象已被放弃)。