我正在阅读这个MSDN引用:
虽然垃圾收集器能够跟踪封装非托管资源的对象的生存期,但它不了解如何清理资源。对于这些类型的对象,.NET框架提供了Object.Finalize方法,当垃圾收集器回收对象使用的内存时,该方法允许对象正确地清理其非托管资源。默认情况下,Finalize方法什么也不做。如果希望垃圾收集器在对象回收对象内存之前对其执行清理操作,则必须重写类中的Finalize方法。
我理解GC是如何工作的,但这让我想到了什么是CleanUp?它是否只是恢复记忆,如果它是,而不是为什么它有不同的名称?
发布于 2010-10-18 02:55:47
他们使用了一个通用的短语,比如“清理”,因为除了恢复内存之外,可能还需要做其他的事情。我可以看到,这可能有点混乱,因为引用提到清理资源和在同一句话中回收内存。在这种情况下,它们的意思是垃圾收集器回收实际调用到非托管库(例如包装类)的托管代码所使用的内存,但将非托管特定的回收过程留给开发人员(关闭文件句柄、释放缓冲区等)。
例如,我有一个包含Graph类的Graphviz包装器库。这个类封装用于创建图、向它们添加节点等的函数。在内部,该类维护一个指向Graphiz本身分配的非托管图结构的指针。对于.NET框架来说,这只是一个IntPtr,它不知道如何在垃圾收集期间释放它。因此,当托管Graph对象不再被使用时,垃圾收集器释放指针所使用的内存,而不是它所指向的数据。为此,我必须实现一个终结器,它调用非托管函数agclose (释放图形所使用的资源的Graphviz函数)。
发布于 2010-10-18 03:06:06
请注意,这也不是完整的故事,因为只有当对象被垃圾收集时才会完成。实际上,您应该尽快释放所有非托管资源(文件句柄、互斥、非托管内存)。您应该看看IDisposable接口,它定义了Dispose()函数。
在可能的情况下,您的处置程序应该运行相同的方法来释放资源,就像终结器那样,但是然后调用GC.SuppressFinalize()来阻止它再次运行(在终结器中),因为在使用实现终结器的对象时,性能会受到轻微的影响。
发布于 2010-10-18 02:54:00
例如,如果您编写的组件使用了一些操作系统资源,如命名管道或内存映射文件。您可以使用finalize操作将资源释放回os。
https://stackoverflow.com/questions/3956314
复制相似问题