vb.net .dispose() 方法有什么作用吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2024021/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 14:35:21  来源:igfitidea点击:

Does the .dispose() method do anything at all?

vb.netmemorydispose

提问by broke

I was experimenting with ways to get rid of some memory leaks within my application the other day when I realized that I know virtually nothing about cleaning up my resources. I did some research, and hoped that just calling the .dispose() would solve all of my problems. We have a table in our database that contains about 65,000 records. Obviously when I fill my dataset from the data adapter, the memory usage can get pretty high. When I called the dispose method on the dataset, I was surprised to find out that NONE of the memory got released. Why did this happen? Clearing the dataset doesn't help either.

前几天,当我意识到我对清理资源几乎一无所知时,我正在尝试消除应用程序中的一些内存泄漏的方法。我做了一些研究,希望只要调用 .dispose() 就可以解决我所有的问题。我们的数据库中有一个包含大约 65,000 条记录的表。显然,当我从数据适配器填充我的数据集时,内存使用量会变得非常高。当我在数据集上调用 dispose 方法时,我惊讶地发现没有任何内存被释放。为什么会这样?清除数据集也无济于事。

回答by Lasse V. Karlsen

IDisposableand thus Disposeis not used to reduced memory pressure, although in some cases it might, but instead used for deterministic cleanup.

IDisposableDispose不用于减少内存压力,尽管在某些情况下它可能会使用,而是用于确定性清理。

Consider this, you construct an object that maintains an active and open connection to your database server. This connection uses resources, both on your machine, and the server.

考虑到这一点,您构建了一个对象,该对象维护与数据库服务器的活动和开放连接。此连接使用您的机器和服务器上的资源。

You could of course just leave the object be when you're done with it, and eventually it'll get picked up by the garbage collector, but suppose you want to make sure at least the resources gets freed, and thus the connection closed, when you're done with it. This is where IDisposable.Disposecomes into play.

您当然可以在完成后将对象留在原处,最终它会被垃圾收集器回收,但是假设您想确保至少释放资源,从而关闭连接,当你完成它时。这就是IDisposable 的地方处置开始发挥作用。

It is used to clean up resources managed by the object.

它用于清理对象管理的资源。

It will, however, not free the managed memory allocated to the object. This is still left to the garbage collector, that will kick in at some later time to do that.

但是,它不会释放分配给对象的托管内存。这仍然留给垃圾收集器,它会在稍后的时间开始执行。

Do you actually have a memory problem, or do you just look at the memory usage in Task Manager or similar and go "that's a bit high."?

您是否真的有内存问题,或者您只是在任务管理器或类似工具中查看内存使用情况并说“有点高。”?

If the latter, then you should just leave it be for now. .NET will run garbage collection more often if you have less memory available, so unless you're in a situation where you get, or might suspect you will get soon, a memory overflow condition, you're probably not going to have any problems.

如果是后者,那么您应该暂时保留它。如果可用内存较少,.NET 将更频繁地运行垃圾回收,因此除非您遇到或可能怀疑很快会遇到内存溢出情况,否则您可能不会遇到任何问题.

Let me explain what I mean by "run less often".

让我解释一下我所说的“少跑”是什么意思。

If you have 8GB of memory in your machine, and only have Windows and Notepad running, most of that memory will be available. When you now run your program, even if it loads minor data blocks into memory, you can keep doing that for a long time, and memory usage will steadily grow. Exactly when the GC will kick in and try to reduce your memory footprint I don't know, but I can almost guarantee you that you will wonder why it gets so high.

如果您的机器有 8GB 内存,并且只运行 Windows 和记事本,那么大部分内存都将可用。当你现在运行你的程序时,即使它把少量的数据块加载到内存中,你可以继续这样做很长时间,内存使用量会稳步增长。我不知道 GC 何时开始并尝试减少您的内存占用,但我几乎可以向您保证,您会想知道为什么它会变得如此之高。

Let's just for the sake of the argument say that your program will eventually use 2GB of memory.

让我们只是为了论证而说您的程序最终将使用 2GB 的内存。

Now, if you run your program on a machine that has less memory available, GC will occur more often, and will kick in on a lower limit, which might keep the memory usage below 500MB or possibly even less.

现在,如果您在可用内存较少的机器上运行您的程序,GC 将更频繁地发生,并且将启动一个较低的限制,这可能会使内存使用量保持在 500MB 以下甚至更少。

The important part to note here is that in order for you to get an accurate picture of how much memory application actually requires, then you can't rely on Task Manager or similar ways to measure it, you need something more targetted.

这里要注意的重要部分是,为了让您准确了解应用程序实际需要多少内存,那么您不能依赖任务管理器或类似的方法来衡量它,您需要更有针对性的东西。

回答by Coincoin

Calling Dispose() will only release unmanaged resources, such as file handles, database connections, unmanaged memory, etc. It will notrelease garbage collected memory.

调用 Dispose() 只会释放非托管资源,例如文件句柄、数据库连接、非托管内存等,不会释放垃圾回收的内存。

Garbage collected memory will only get released at the next collection. Usually when the application domain memory is deamed full.

垃圾收集的内存只会在下一次收集时释放。通常当应用程序域内存已满时。

回答by slugster

I'm going to point out something here that hasn't been explicitly mentioned: calling Dispose()will only clean up (free) unmanaged resources if the developer of the component has coded it.

我将在这里指出一些尚未明确提及的内容:Dispose()如果组件的开发人员对其进行了编码,则调用只会清理(免费)非托管资源。

What I mean is this: if you suspect you have a memory leak, calling Dispose()is not going to fix it if the original developer has done a lousy job and not correctly freed up unmanaged resources. For a bit more info, check this blog post. Take note of the statement The behaviour of Dispose is defined by the developer.

我的意思是:如果你怀疑你有内存泄漏,如果原始开发人员做了糟糕的工作并且没有正确释放非托管资源,则调用Dispose()不会修复它。有关更多信息,请查看此博客文章。请注意声明Dispose 的行为是由开发人员定义的。

回答by supercat

Some objects will ask one or more other entities to do something on its behalf until further notice, to the detriment of other entities. If an object which did so were to disappear without informing the former entities that their services were no longer needed, those entities would continue to uselessly act on behalf of an object that no longer needed them, to the continuing detriment of other entities that would want to use them.

某些对象会要求一个或多个其他实体代表其做某事,直至另行通知,这会损害其他实体的利益。如果这样做的对象在没有通知前实体不再需要它们的服务的情况下消失,则这些实体将继续代表不再需要它们的对象无用地行动,从而继续损害其他想要的实体使用它们。

In many cases, for an object "George" to tell an outside entity "Joe" that its services were no longer needed, George would have to know that itsservices were no longer needed. There are two normal means via which that can happen in .NET, finalization and IDIsposable.

在许多情况下,如果对象“George”告诉外部实体“Joe”不再需要它的服务,George 必须知道不再需要它的服务。在 .NET 中可以通过两种正常方式实现,即完成和IDIsposable.

If an object overrides a method called Finalize, then when the object is created the .NET garbage collector will add it to a list of objects with registered finalizers. If the GC discovers that there exists no rooted reference to the object other than that list, the GC will remove the object from that list and add it to a strongly-rooted queue of objects which should have their Finalizemethod called as soon as possible. Such an object can then use its Finalizemethod to inform other entities that their services are no longer required.

如果一个对象覆盖了一个名为 的方法Finalize,那么在创建该对象时,.NET 垃圾收集器会将它添加到一个已注册终结器的对象列表中。如果 GC 发现除该列表之外不存在对该对象的根引用,则 GC 将从该列表中删除该对象并将其添加到应Finalize尽快调用其方法的强根对象队列中。然后,这样的对象可以使用其Finalize方法通知其他实体不再需要它们的服务。

Although finalization-based cleanup can sometimes work, there's no guarantee of timeliness. At one point during the design of .net Microsoft may have intended that finalization would be the primary cleanup method, but for a variety of reasons it cannot safely be relied upon.

尽管基于最终确定的清理有时可以奏效,但不能保证及时性。在 .net 设计过程中的某一时刻,Microsoft 可能打算将最终确定作为主要的清理方法,但由于各种原因,不能安全地依赖它。

The other cleanup approach, which should be the focus of one's efforts, is IDisposable. Basically, the idea behind IDisposableis simple: for every object that implements IDisposable, there should be one entity (generally either an object or a nested execution scope) which is responsible for ensuring that that object's IDisposable.Disposemethod will get called sometime within the lifetime of the universe (which would imply sometime while a reference to the object still exists), and preferably as soon as code can tell that the object's services will no longer be required.

另一种清理方法,应该是人们努力的重点,是IDisposable. 基本上,背后的想法IDisposable很简单:对于每个实现 的对象,IDisposable都应该有一个实体(通常是一个对象或一个嵌套的执行范围)负责确保该对象的IDisposable.Dispose方法将在 Universe 的生命周期内的某个时间被调用(这意味着某个时候对对象的引用仍然存在),并且最好是在代码可以告诉不再需要对象的服务时。

Note that IDisposable.Disposegenerally promises that any outside entities which had been asked to do something on an object's behalf will be told that they no longer need to do so, but such a promise does not imply that the number of entities is non-zero. If an object hasn't asked any outside entities to do anything on its behalf, then delivering a message "all" such entities doesn't require doing anything at all. On the other hand, the fact that a Disposemethod may do nothing in some cases doesn't mean that it's guaranteed never to do anything in any case, nor that failure to call it in those cases where it would do something won't have detrimental effects.

请注意,IDisposable.Dispose通常承诺任何被要求代表对象做某事的外部实体将被告知他们不再需要这样做,但这样的承诺并不意味着实体的数量非零。如果一个对象没有要求任何外部实体代表它做任何事情,那么传递消息“所有”这样的实体根本不需要做任何事情。另一方面,一个Dispose方法在某些情况下可能什么都不做这一事实并不意味着它在任何情况下都不会做任何事情,也不意味着在它会做某事的情况下不调用它不会有不利影响效果。