手动销毁 C# 对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1987251/
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-08-06 22:25:28  来源:igfitidea点击:

Manually destroy C# objects

c#destructoridisposableusing

提问by East of Nowhere

I am fairly new to learning C# (from Java & C++ background) and I have a question about manual garbage disposal: is it even possible to manually destroy an object in C#? I know about the IDisposableinterface, but suppose I'm dealing with a class which I didn't write and it doesn't implement it? It wouldn't have a .Dispose()method, so that and using { }is out, and .Finalizeis always either protectedor privateso that's not an option either.

我刚开始学习 C#(来自 Java 和 C++ 背景),我有一个关于手动垃圾处理的问题:甚至可以在 C# 中手动销毁对象吗?我知道IDisposable接口,但假设我正在处理一个我没有编写的类并且它没有实现它?它不会有一个.Dispose()方法,所以那个和using { }出来了,而且.Finalize总是或者protected或者private所以这也不是一个选择。

(I am just trying to learn what is possiblein C# in this case. I suppose if all else fails I could inheritthe hypothetical ImNotDisposableclass so that it doesimplement IDisposable.)

(我只是想了解什么是可能在C#在这种情况下,我想,如果一切都失败了,我可以继承的假设ImNotDisposable类,以便它实现IDisposable。)

采纳答案by Joel Coehoorn

You don't manually destroy .Net objects. That's what being a managed environment is all about.

您无需手动销毁 .Net 对象。这就是托管环境的全部意义所在。

In fact, if the object is actually reachable, meaning you have a reference you can use to tell the GC which object you want to destroy, collecting that object will be impossible. The GC will nevercollect any object that's still reachable.

事实上,如果对象实际上是可达的,这意味着你有一个可以用来告诉 GC 你想要销毁哪个对象的引用,收集那个对象将是不可能的。GC永远不会收集任何仍可访问的对象。

What you can do is call GC.Collect()to force a general collection. However, this almost never a good idea.

您可以做的是调用GC.Collect()强制一般收集。然而,这几乎从来都不是一个好主意。

Instead, it's probably better to simply pretendany object that doesn't use unmanaged resources and is not reachable by any other object in your program is immediately destroyed. I know this doesn't happen, but at this point the object is just a block of memory like any other; you can't reclaim it and it will eventually be collected, so it may just as well be dead to you.

相反,最好简单地假设任何不使用非托管资源并且程序中的任何其他对象都无法访问的对象立即被销毁。我知道这不会发生,但在这一点上,对象只是一个像任何其他对象一样的内存块;你不能收回它,它最终会被收集起来,所以它对你来说也可能已经死了。

One final note about IDisposable. You should only use it for types that wrap unmanagedresources: things like sockets, database connections, gdi objects, etc, and the occasional event/delegate subscription.

关于IDisposable. 您应该只将它用于包装非托管资源的类型:诸如套接字、数据库连接、gdi 对象等,以及偶尔的事件/委托订阅。

回答by Eilon

If the object is not reachable then you can call GC.Collect()and the object will be destroyed. The concept of IDisposablehas nothing to do with the CLR and is mostly for user code to implement to perform additionaldisposal logic. Calling Dispose() on an object will not free the object itself from memory, though it may very well dispose any resources that this object references.

如果对象不可访问,那么您可以调用GC.Collect()并且对象将被销毁。的概念IDisposable与 CLR 无关,主要是供用户代码实现以执行额外的处理逻辑。对对象调用 Dispose() 不会从内存中释放对象本身,尽管它很可能会释放该对象引用的任何资源。

I should add that while what I said is a way to achieve this, in 99.9999% of applications you should never call GC.Collect()because it'll often degradethe performance of your application instead of improving it.

我应该补充一点,虽然我所说的是一种实现这一目标的方法,但在 99.9999% 的应用程序中,您永远不应该调用,GC.Collect()因为它通常会降低应用程序的性能而不是改进它。

回答by Jay Bazuzi

No, you can't destroy a specific object.

不,您不能销毁特定对象。

It is possible to invoke the garbage collector, which will look for objects to destroy, but it's almost never a good idea.

可以调用垃圾收集器,它会寻找要销毁的对象,但这几乎不是一个好主意。

回答by Mark Seemann

You canforce the garbage collector to run after the variable you want to destroy goes out of scope, but you normally don't want to do that, as the garbage collector is more efficient if left to do its own work.

可以在要销毁的变量超出范围后强制垃圾收集器运行,但您通常不想这样做,因为如果让垃圾收集器自行完成工作,则效率更高。

Forcing garbage collection can be done with GC.Collect, but don't do it. In my 10 years as a .NET developer, I have never needed it.

可以使用GC.Collect强制垃圾收集,但不要这样做。在我作为 .NET 开发人员的 10 年中,我从未需要它。

回答by Scott Davies

It's not possible to destroy an object in a deterministic fashion. The CLR determines when the flagged object is reclaimed. This means that while you can flag an object for reclamation and ensure that managed and unmanaged resources are tidied up for disposal (by implementing the IDisposable pattern), the actual time the memory is released is up to the CLR. This is different from C++ where you could actually delete something and it would be released then.

以确定性的方式销毁对象是不可能的。CLR 确定何时回收标记的对象。这意味着虽然您可以标记一个对象进行回收并确保整理托管和非托管资源以供处置(通过实现 IDisposable 模式),但释放内存的实际时间取决于 CLR。这与 C++ 不同,在 C++ 中,您可以实际删除某些内容,然后将其释放。

回答by bashmohandes

You can'tmanually destroy an object "like C++ delete", all what you can do is just close any exclusive resources the object has acquired and null all references to this object, so the GC can collect it, also don't call GC.Collect() by yourself, the GC process is expensive, as it has to suspend all other threads to safely collect the objects from memory, so just trust the GC, and it will kick off when needed.

不能像 C++ delete 那样手动销毁一个对象,你所能做的就是关闭该对象获得的所有独占资源并将对该对象的所有引用归零,这样 GC 就可以收集它,也不要调用 GC .Collect() 自己,GC 过程很昂贵,因为它必须挂起所有其他线程才能从内存中安全地收集对象,所以只要相信 GC,它就会在需要时启动。

回答by Josh

Although you can trigger garbage collection (you need to trigger GC for all generations because you can't be sure which generation the finalizable object is in) you cannot necessarily force finalization of a particular object. You can only depend upon assumptions about how the garbage collector works.

尽管您可以触发垃圾回收(您需要为所有代触发 GC,因为您无法确定可终结对象在哪一代),但您不一定强制特定对象的终结。您只能依赖关于垃圾收集器如何工作的假设。

Furtnermore, since finalization happens on its own thread, you should call WaitForPendingFinalizersafter triggering garbage collection.

此外,由于终结发生在它自己的线程上,因此您应该在触发垃圾回收后调用WaitForPendingFinalizers

GC.Collect(GC.MaxGeneration);
GC.WaitForPendingFinalizers();

As was noted by others, this can actually hurt your application's performance because unnecessarily invoking the GC can promote otherwise short-lived objects into higher generations which are more expensive to collect and are collected less frequently.

正如其他人所指出的那样,这实际上会损害您的应用程序的性能,因为不必要地调用 GC 可以将其他生命周期较短的对象提升到更高的代,这些对象的收集成本更高且收集频率更低。

Generally speaking, a class that implements a finalizer (destructor) and does not implement IDisposable is frowned upon. And anything that implements IDisposable should be calling it's finalizer logic and supressing itself from finalization at garbage collection.

一般来说,实现终结器(析构函数)而没有实现 IDisposable 的类是不受欢迎的。任何实现 IDisposable 的东西都应该调用它的终结器逻辑,并在垃圾收集时抑制自己的终结。

Jeff Richter recently posted a nice little trick for receiving a notification when garbage collection occurs.

Jeff Richter 最近发布了一个很好的小技巧,用于在垃圾收集发生时接收通知

Another great article on Garbage Collector Basics and Performance Hintsby Rico Mariani (MSFT)

Rico Mariani (MSFT)关于垃圾收集器基础知识和性能提示的另一篇很棒的文章

回答by MrGuest123

Say you have a class matrix and you created two matrix objects aMatrixand bMatrix. In C# you can manually destroy (finalize) an object like so:

假设您有一个矩阵类,并且创建了两个矩阵对象aMatrixbMatrix. 在 C# 中,您可以像这样手动销毁(完成)一个对象:

aMatrix = null;

GC.Collect();

The garbage collector will notice that your aMatrixis null and will destroy (finalize) it. Whether or not this is a good idea is a different story.

垃圾收集器会注意到您的aMatrix值为空并销毁(完成)它。这是否是一个好主意是另一回事。