某些类型(如Image)如何使用Dispose()方法进行Dispose

本文关键字:Dispose 方法 Image 类型 何使用 | 更新日期: 2023-09-27 18:13:39

假设我有一个大的Image对象,如果我调用这个对象的Dispose()方法,我可以很容易地看到我的应用程序的内存消耗减少了,因为我刚刚从内存中清除了对象。

但是,如果我有我自己的类型/类,并想要处置它的一个实例,其中,让我们说,包含一个byte[]数组(我认为这是Image类内部相同的东西)。我该如何实现IDisposable,这样当Dispose()被调用时,byte[]会立即从内存中清除。不需要我等待GC ?

如果是string而不是byte[]呢?

某些类型(如Image)如何使用Dispose()方法进行Dispose

内存消耗在以下两种情况下减少:

  1. 垃圾收集器已经释放内存,
  2. 执行非托管代码,立即释放内存。

图像数据示例是第二种情况。映像由操作系统保存,当您释放映像时,操作系统将被调用来释放映像缓冲区。这是操作系统的工作,因为操作系统是在屏幕上渲染图像的,这取决于硬件和驱动程序。除此之外,图形化操作系统在处理图像数据方面做了极大的优化——难怪它在需要的时候被用来处理图像。

当您创建自己的一次性类时,情况完全相反。对于内存占用,执行dispose实际上什么也不做。即使是垃圾收集也不会减少内存使用,只要有一个活动指针指向被处置的类。

类应该实现IDisposable只有当它分配一些非托管资源-文件句柄,图像,套接字(从操作系统的角度来看,这只是一种文件句柄),等等。方法应该只释放非托管资源。将字段设置为null并执行类似的愚蠢操作是没有意义的。

. net中的对象只有在存在某种引用的情况下才存在。不存在的对象不包含对任何东西的引用。如果在垃圾收集周期中发现一个对象除了作为WeakReference目标之外在任何地方都没有对它的引用,系统将使这些WeakReference对象无效,因此这些对象将不再有指向它们的任何引用,从而停止存在。如果对一个对象的唯一非弱引用是在已经注册了Finalize方法的系统对象列表中,那么该对象将从该列表中删除,并添加到应该在第一次机会运行Finalize方法的系统对象列表中。一旦系统运行一个对象的Finalize方法,它将从后一个列表中删除,除非引用已经存储在其他地方,否则它将不复存在。

Image有一个dispose方法的原因是它的构造经常要求创建非。net对象的东西和/或要求外部实体代表它做一些事情(例如授予对文件的独占读访问权)。如果在没有调用Dispose的情况下放弃了Bitmap,并且如果它没有Finalize方法,则Bitmap对象将停止存在,但它请求创建的任何外部对象将继续存在,并且代表其行事的任何外部实体将继续存在。

因为字节数组的创建不需要构造任何非. net对象的东西,也不需要任何外部实体代表它做任何事情,所以不需要一个不再需要做任何事情的数组,除了停止存在。