2009-11-08 105 views
3

我对.net比较陌生。正如我试图掌握垃圾收集的概念(从“通过C#的CLR”),我开始了解垃圾收集方法的强大程度。但是,当我阅读时,我明白应该释放分配的本地资源。其方法为:
我)让我们的类型从CriticalFinalizerObject
ii)使用处置利用格局使用语句在我的脑海C# - 发布本地资源

问题得出:
1)我有点困惑时使用什么?
2)对于CLR来说,将非垃圾对象向下移动来压缩堆也不是更重要吗?
3)任何其他文章建议阅读和理解更彻底的概念。

请纠正我,如果我在我的任何上述声明
问候,
贾斯汀·塞缪尔的错。

+0

感谢所有的意见。倾听来自你们的想法,帮助很多!谢谢!! :) – 2009-11-09 05:26:26

回答

4
  1. 要从CriticalFinalizerObject在你的类型的使用应被视为一个constrained execution region或CER短的情况下获得。 CER是一个必须完成的代码领域,根据我的经验,这些代码通常不会被使用(但这并不意味着它们没有用处)。

    执行IDisposable接口有点不同 - 这种接口提供了一种确定性的清理方式,一旦消费者不再需要,就可以在你的类型后进行清理。这通常用于清理非托管资源(如数据库连接和文件句柄)。

  2. 是的,垃圾收集器必须在其紧凑阶段将许多对象移动到内存中,但这并不是真的可以提供帮助。当虚拟内存变得碎片化时,对象将被移动,这是不受控制的,因为垃圾收集器完全负责托管堆。在这种情况下,最好的做法是让您的类型尽可能最好地工作,并且只有在仪器证明它​​已成为问题时才担心垃圾收集器。

  3. 我会看看我是否可以找到一些更有用的文章,但CLR通过C#几乎是最好的信息,你将能够找到关于这个主题。

+0

是的安德鲁,你是对的。 “通过C#CLR”是从概念上学习.net的绝佳资源。你能建议我学习c#概念的好链接吗? – 2009-11-09 05:28:01

2

尽可能使用Dispose模式和using。只有在无法确定性地知道何时可以释放特殊资源时才使用终结器。如果你发现这种情况经常发生,你可能做错了什么。

垃圾收集是一个很深的话题。有关垃圾收集的总体概述及其在CLR中的实现,特别是this article似乎很稳固。这是从十年前开始的,但好的CS就像是好的数学:它的年龄很好。

3

我推荐这篇文章在Dispose, Finalization, and Resource Management

你使用什么取决于你做什么类型的编程。根据个人经验,我发现:

  • 大多数情况下,我唯一需要做的资源管理是将任何实现IDisposable的对象封装在使用块中。
  • 当我的类拥有一个实现IDisposable的对象时,有时我必须实现Basic Dispose Pattern(无终结器)。
  • 我从来没有必须从CriticalFinalizerObject派生。

您的里程可能会有所不同。

0

安全与非托管手柄

工作可靠释放非托管手柄而不约束的执行区域(的CER)是不可能的。由于ThreadAbortOutOfMemory例外可能会出现在您的终结器中,您总是会遇到竞争状况。所以你需要使用CERs。

CriticalFinalizerObject在内部使用约束执行区域,在最终化过程中优先化,还有一些其他功能使得它“相对容易”相对容易,并且在需要时总是释放非托管资源。一般情况下,你应该从SafeHandleCriticalFinalizerObject派生手柄握住非托管对象。这样你就知道当物体被垃圾收集时它们会被清理干净,即使它是一种不寻常的关机情况,如ThreadAbortException

使用什么()和IDisposable的增加

using()和IDisposable模式让你急切地释放非托管资源 - 如您使用的是他们做尽快。如果你不用using()来处理你的对象,他们会坚持到下一次垃圾收集。这是低效率的。

所以CriticalFinalizerObject是关于如何确保非托管资源最终释放而using()是关于如何确保非托管资源被迅速释放。两者应该一起使用。

另外using()适用于纯粹的托管代码,例如,如果您正在缓存一个对象池,则Dispose()可以将对象返回到池中。

GC

压实堆可以更有效,因为持续时间长的对象最终都挤在一起时压实堆。在.NET Framework中,只有最低的一代(最近创建的对象)被严格压缩。 Theres在引擎盖下进行了很多优化。阅读起来很有趣,但对于完成工作并不重要。如果您想了解更多信息,请搜索关于“世代垃圾收集”的文章。