c#内存分配和释放模式
因为C#使用垃圾收集。何时需要使用.Dispose释放内存 我意识到有一些情况,所以我会尽量列出我能想到的情况c#内存分配和释放模式,c#,.net,memory-management,memory-leaks,C#,.net,Memory Management,Memory Leaks,因为C#使用垃圾收集。何时需要使用.Dispose释放内存 我意识到有一些情况,所以我会尽量列出我能想到的情况 如果我关闭一个包含GUI类型对象的表单,这些对象是否会被取消引用并因此被收集 如果我使用new创建一个本地对象,我应该在方法退出之前处理它,还是让GC处理它?在这种情况下,什么是良好做法 在任何时候强制GC都是可以理解的吗 GC在收集其对象时是否收集事件 看看这个问题: 如果您的类实例化IDisposable接口,这(可能)意味着它拥有必须直接处置的系统资源。实现这一点的一个简单方法
using(var g = Graphics.FromBitmap(bmp))
{
//Do some stuff with the graphics object
}
根据@Matt S在我提到的问题中的回答
关于您的问题:
理论上,如果您已经正确定义了componentry,那么在对象上调用Dispose()永远都不应该必需,因为终结器最终应该处理它 也就是说,每当您使用实现IDisposable的对象时,最好在使用完该对象后立即对其调用Dispose() 对于您的一些具体观点: 1) 如果您知道表单已“完成”,则可以对其调用Dispose()。这将强制在该时间点清理和表单关联的非托管资源 2) 在这种情况下:如果您的对象仅在该方法中使用,请改用“使用”: 3) 很少有理由这样做,但总的来说,没有
4) 事件是一个委托-与委托关联的内存将在委托本身解除根目录后收集,这通常发生在相关对象解除根目录时。您应该对每个实现IDisposable的类调用
Dispose
。如果它不需要Dispose
ed,那么它就不会实现IDisposable
至于你的其他问题:
Controls
集合时,该控件将在窗体关闭时自动释放,因此无需执行任何操作IDisposable
,则需要调用Dispose
。例如,如果您转到新文件流(…)
,则需要释放文件流,因为它实现了IDisposable。我建议您仔细阅读使用C#中的构造的,这使得处理IDisposable
对象更容易
如果您使用的是<代码> IDISPABLE < /COD>对象,请考虑使用<代码>使用语句来自动处理您的处理。
如Reed Copsiy所说,通常不必调用Debug。
可能会造成问题的一种情况是,静态对象持有其他对象的引用,而这些对象在其他任何地方都不再使用。以下代码显示了一个示例:Form_Load(...)
MyState.Instance.AddressChanged += this.User_AddressChanged;
End
如果出于某种原因,在卸载表单时,代码未注销事件处理程序,则状态对象仍将引用表单实例。可能的重复:另请参阅:通常,对于不会返回的非托管资源,将实现IDisposable,当GC清理对象时关闭或最佳使用—托管对象始终由GC清理。请参见IDisposable@For#2,无论您是否调用Dispose(),GC都会处理托管代码中的对象#1和内置的“GUI类型对象”将被收集,无论您是否调用Dispose()。另请看@George:我不认为它们与任何一个都是重复的。我也许应该澄清一下,因为我的主要问题是什么时候应该明确地释放内存,什么时候不应该担心它。答案似乎很清楚,也就是说,如果一个对象可以被释放,那么它总是被释放,这是首选的模式。我将开始对所有一次性物品使用它,以遵循一致的模式。谢谢你的回答。你的回答似乎与其他人的回答相冲突。你为什么说让GC来处理?另外,它似乎与您的原始语句有一些冲突?如果您只是使用new创建一个对象,但它没有实现IDisposable接口,那么让GC来处理它。但是,如果它实现了IDisposable,那么您必须按照#1的规定在释放它之前处理它。如果声明一个新的int数组,int不会实现IDisposable,因此您可以让gc来处理它。#1:True但是如果对象是在设计时添加的,但没有添加到控件的集合中呢?当窗体关闭时,它是否仍将被释放
Form_Load(...)
MyState.Instance.AddressChanged += this.User_AddressChanged;
End