【问题标题】:Clean Up Vs Memory Reclaim in .Net.Net 中的清理与内存回收
【发布时间】:2010-10-18 02:48:39
【问题描述】:

我正在阅读此 MSDN 参考:

虽然垃圾收集器能够 跟踪对象的生命周期 封装了一个非托管 资源,没有具体的 关于如何清理的知识 资源。对于这些类型的对象, .NET 框架提供 Object.Finalize 方法,它允许 清理其非托管对象 资源妥善当垃圾 收集器回收使用的内存 物体。默认情况下,Finalize 方法什么都不做。如果你想要 垃圾收集器执行清理 在它之前对你的对象进行操作 回收对象的内存,你必须 覆盖您的 Finalize 方法 类。

我了解 GC 的工作原理,但这让我想到 CleanUp 到底是什么?如果它不是为什么它具有不同的名称,它只是在回收内存吗?

【问题讨论】:

    标签: c# .net garbage-collection


    【解决方案1】:

    请注意,这也不是全部,因为最终确定仅在对象被垃圾回收时发生。实际上,您应该尽快释放所有非托管资源(文件句柄、互斥体、非托管内存)。你应该看看IDisposable 接口,它定义了Dispose() 函数。

    您的处理程序应尽可能运行与终结器相同的方法来释放资源,但随后调用 GC.SuppressFinalize() 以阻止它再次运行(在终结器中),因为使用实现的对象时性能会受到轻微影响终结者。

    【讨论】:

      【解决方案2】:

      他们使用了诸如“清理”之类的通用短语,因为除了回收内存之外,可能还需要做其他事情。我可以看到这可能有点令人困惑,因为引用在同一个句子中提到了清理资源和回收内存。在这种情况下,它们的意思是垃圾收集器回收托管代码使用的内存,这些代码实际调用到非托管库(例如包装类)中,但将非托管特定回收过程留给开发人员(关闭文件句柄、释放缓冲区等)。

      例如,我有一个 Graphviz 包装库,其中包含一个 Graph 类。此类包装用于创建图形、向其添加节点等的函数。在内部,此类维护指向由 Graphiz 本身分配的非托管图形结构的指针。对于 .NET Framework,这只是一个IntPtr,它不知道如何在垃圾回收期间释放它。因此,当不再使用托管的Graph 对象时,垃圾收集器会释放指针使用的内存,但不会释放它指向的数据。为此,我必须实现一个终结器,它调用非托管函数agclose(释放图形使用的资源的 Graphviz 函数)。

      【讨论】:

        【解决方案3】:

        例如,如果您编写了一个使用某些操作系统资源(如命名管道或内存映射文件)的组件。您可以使用 finalize 操作将资源释放回操作系统。

        【讨论】:

          【解决方案4】:

          清理非托管资源可能包括关闭网络连接、文件、数据库连接等。当然,也可能包括为该资源释放内存。

          【讨论】:

            【解决方案5】:

            CleanUp 在这里意味着释放任何有限资源(硬盘、网络带宽、声卡、内存、CPU 等),并且由于 .NET 没有对非托管代码的托管引用,它可以让您在在 GC 交换之前使用 Finalize() 方法的正确时机。如果您不CleanUp,您最终会得到一些处于未知状态的孤儿非托管代码,这些代码仍在使用资源。最好通过在对象上调用Dispose() 来实现IDisposableCleanUp

            【讨论】:

              猜你喜欢
              • 2015-11-02
              • 1970-01-01
              • 2010-11-13
              • 2023-03-12
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-10-07
              • 2021-11-24
              相关资源
              最近更新 更多