我正在尝试在我的应用程序中摆脱一些内存泄漏的方法,前几天我意识到我几乎不了解清理我的资源。我做了一些研究,并希望只需调用.dispose()即可解决我的所有问题。我们的数据库中有一个包含大约65,000条记录的表。显然,当我从数据适配器填充数据集时,内存使用率可能会非常高。当我在数据集上调用dispose方法时,我惊讶地发现没有内存被释放。为什么会这样?清除数据集也无济于事。
答案 0 :(得分:26)
IDisposable因此Dispose不会用来降低内存压力,尽管在某些情况下它可能会用于确定性清理。
考虑到这一点,您构造了一个维护与数据库服务器的活动和开放连接的对象。此连接使用计算机和服务器上的资源。
当然,当你完成它时,你可以保留对象,最终它会被垃圾收集器拾取,但是假设你想要确保至少释放资源,从而当你完成它时,连接关闭。这是IDisposable。Dispose发挥作用的地方。
用于清理对象管理的资源。
但是,它不会释放分配给该对象的托管内存。这仍然留给垃圾收集器,它将在稍后的某个时间开始执行。你真的有内存问题吗,或者你只看一下任务管理器或类似的内存使用情况,然后去“那有点高。”?
如果是后者,那么你应该暂时离开它。如果你有更少的可用内存,.NET将更频繁地运行垃圾收集,所以除非你遇到的情况,或者可能怀疑你很快就会出现内存溢出情况,否则你可能不会遇到任何问题
让我通过“少跑”来解释我的意思。
如果您的计算机中有8GB内存,并且只运行Windows和记事本,则大部分内存都可用。当您现在运行程序时,即使它将次要数据块加载到内存中,您也可以长时间保持这种状态,并且内存使用量将稳步增长。确切地说,当GC开始并试图减少你的内存占用时我不知道,但我几乎可以向你保证,你会想知道为什么它变得如此之高。
让我们只是为了争论说你的程序最终会使用2GB的内存。
现在,如果您在可用内存较少的计算机上运行程序,GC将更频繁地发生,并且会在下限启动,这可能会使内存使用率保持在500MB以下甚至更低。
这里要注意的重要部分是,为了让您准确了解实际需要的内存应用程序,那么您不能依赖任务管理器或类似的方法来测量它,你需要更具针对性的东西。
答案 1 :(得分:4)
调用Dispose()只会释放非托管资源,例如文件句柄,数据库连接,非托管内存等。它将不释放垃圾回收内存。
垃圾收集的内存只会在下一个集合中释放。通常当应用程序域内存被完全扩展时。
答案 2 :(得分:3)
我将在此处指出一些未明确提及的内容:如果组件的开发人员对其进行编码,则调用Dispose()
将仅清理(免费)非托管资源。
我的意思是这样的:如果你怀疑你有内存泄漏,如果原始开发人员做了糟糕的工作而没有正确释放非托管资源,那么调用Dispose()
不会修复它 / em>的。有关详细信息,请check this blog post。请注意语句 Dispose的行为由开发人员定义。
答案 3 :(得分:1)
有些对象会要求一个或多个其他实体代表它做某事,直到另行通知为止,这会损害其他实体。如果这样做的对象在没有告知前实体不再需要其服务的情况下消失,那些实体将继续无用地代表不再需要它们的对象行动,继续损害其他想要的实体。使用它们。
在许多情况下,对于“George”对象告诉外部实体“Joe”不再需要其服务,George必须知道不再需要其服务。有两种常规方法可以在.NET中完成,最终确定和IDIsposable
。
如果对象覆盖名为Finalize
的方法,则在创建对象时,.NET垃圾收集器会将其添加到具有已注册终结器的对象列表中。如果GC发现除了该列表之外没有对该对象的根对引用,则GC将从该列表中删除该对象并将其添加到强根源对象队列中,这些对象应该将其Finalize
方法调用为尽快。然后,此类对象可以使用其Finalize
方法通知其他实体不再需要其服务。
尽管基于定型的清理有时可以起作用,但并不能保证及时性。在设计.net期间的某个时刻,微软可能打算将最终确定作为主要的清理方法,但出于各种原因,它无法安全地依赖。
另一种清理方法应该是一个人努力的焦点,IDisposable
。基本上,IDisposable
背后的想法很简单:对于实现IDisposable
的每个对象,应该有一个实体(通常是对象或嵌套的执行范围),它负责确保该对象的{{1} 1}}方法将在Universe的生命周期内的某个时间被调用(这意味着某个时候对对象的引用仍然存在),并且最好只要代码可以告诉对象的服务将不再需要。
请注意,IDisposable.Dispose
通常承诺任何被要求代表某个对象做某事的外部实体将被告知他们不再需要这样做,但这样的承诺并不意味着实体不为零。如果一个对象没有要求任何外部实体代表它做任何事情,那么传递“所有”这样的实体的消息不需要做任何事情。另一方面,IDisposable.Dispose
方法在某些情况下可能什么也不做的事实并不意味着它保证在任何情况下都不会做任何事情,也不意味着在那些它会做某事的情况下不能做任何事情。不会产生不利影响。