某些类型如Image可以使用Dispose()方法进行处理

时间:2013-05-15 18:53:12

标签: c# garbage-collection dispose idisposable

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

但是如果我拥有自己的类型/类并且想要处理它的一个实例,比如说,它包含一个byte[]数组(我认为这与Image类相同内部)。我将如何实施IDisposable,以便在调用Dispose()byte[]立即从内存中释放出来。没有我等待GC

如果是string而不是byte[]怎么办?

2 个答案:

答案 0 :(得分:2)

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

Image有一个dispose方法的原因是它的构造经常要求创建不是.NET对象的东西和/或要求外部实体代表它做事情(例如授予对它的独占读访问权限)一份文件)。如果Bitmap被放弃而没有Dispose被调用,并且如果它没有Finalize方法,则Bitmap对象将不再存在,但任何外部其请求的创建将继续存在的对象,代表它的任何外部实体将继续这样做。

因为创建一个字节数组不需要构造任何不是.NET对象的东西,也不需要任何外部权限代表它做任何事情,所以不需要一个不是的数组除了不再存在以外,还需要做更长的事情。同样地,对于拥有这样一个数组的对象。

答案 1 :(得分:2)

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

  1. 垃圾收集器释放了内存,
  2. 执行了非托管代码,即时释放了内存。
  3. 图像数据示例是第二种情况。图像由操作系统保存,当您处理图像时,会调用操作系统来释放图像缓冲区。这是操作系统的工作,因为操作系统是在屏幕上呈现图像的系统,然后依赖于硬件和驱动程序。除此之外,图形操作系统经过极其优化,可以处理图像数据 - 难怪它会在需要时用于处理图像。

    创建自己的一次性课程时完全相反。关于内存占用,执行dispose实际上什么都不做。只要存在指向已处置类的实时指针,即使是垃圾收集也不会减少内存使用量。

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

相关问题