在.Net中清理Vs内存回收

我正在阅读这个MSDN参考资料:

虽然垃圾收集器能够跟踪封装非托管资源的对象的生命周期,但它没有关于如何清理资源的具体知识。 对于这些类型的对象,.NET Framework提供了Object.Finalize方法,该方法允许对象在垃圾回收器回收对象使用的内存时正确地清理其非托管资源。 默认情况下,Finalize方法什么也不做。 如果您希望垃圾回收器在回收对象内存之前对对象执行清理操作,则必须重写类中的Finalize方法。

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


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

作为一个例子,我有一个包含Graph类的Graphviz包装库。 这个类包装了用于创建图的函数,为它们添加节点等。在内部,这个类保存了一个指向Graphiz自身分配的非托管图结构的指针。 对于.NET Framework,这仅仅是一个IntPtr ,它不知道如何在垃圾收集期间释放它。 所以,当一个被管理的Graph对象不再被使用时,垃圾回收器将释放指针使用的内存,但不会释放它指向的数据。 为此,我必须实现一个调用非托管函数agclose (释放图形所用资源的Graphviz函数)。


请注意,这不是完整的故事,因为只有当对象被垃圾收集时才会进行最终处理。 实际上,您应该尽快释放所有非托管资源(文件句柄,互斥锁,非托管内存)。 你应该看看IDisposable接口,它定义了Dispose()函数。

只要有可能,你的垃圾处理器应该运行相同的方法来释放终结器所需的资源,但是随后调用GC.SuppressFinalize()来阻止它再次运行(在终结器中),因为在使用实现终结器的对象时性能会受到很小的影响。


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

链接地址: http://www.djcxy.com/p/54503.html

上一篇: Clean Up Vs Memory Reclaim in .Net

下一篇: What is the difference in managed and unmanaged code, memory and size?