如果有其他对象指向它,可以释放内存吗?

时间:2009-07-01 07:07:46

标签: c#

我有这样的代码:

    public class A: IDisposable
    {
       public CPlusCode cPlusCode{get;set;}

    public void CallB()
    {
       using(bCode = new B(cPlusCode))
       {
              //do everything in B
       }
    }

   public void Dispose()
   {
         cPlusCode.Dispose();
    }
    }

    public class B: IDisposable
    {
    private CPlusCode cpp;
      public B(CPlusCode cPlus)
    {
    cpp= cPlus;
    }
    public void Dispose()
   {
   cpp.Dispose();
  //dispose everything
    }
    }

   public static void Main()
   {
             for(int i=0; i<100000; i++)
                {
                      var aObject = new A();
                     aObject .CallB();
                }
    }

问题在于,当我执行Main时,B占用了大量内存来实例化,从我的观察来看,程序吃掉的内存似乎没有被释放。 / p>

如果有其他对象指向它,可以释放内存吗?

5 个答案:

答案 0 :(得分:6)

IDisposable与回收托管内存无关。 IDisposable允许类型释放未由垃圾收集处理的资源,例如句柄等。对于普通的.NET类型,垃圾收集器将在不再引用对象时处理回收内存。

答案 1 :(得分:2)

GC会在确定需要时运行,因此“及时”不相关。当它发生时它会发生;即它是非确定性的

答案 2 :(得分:2)

Dispose只是一种方法。它根本不需要做任何事情。

在对象上调用Dispose后,该对象仍然存在,但无法再安全使用。但是,运行时无助于强制执行此操作。 Dispose的一个“可靠”实现(一个旨在帮助捕获错误的实现)会在对象内部将_disposed标志设置为true,如果对象上的每个其他方法都将抛出ObjectDisposedException该标志为true(Dispose方法本身应该静默忽略进一步的调用)。但这完全取决于实施者在实施这种模式方面的进展程度。

一个例子是FileStream。当它有一个打开的文件时,进程的句柄计数将增加1.当你在其上调用Dispose时,句柄计数将减少。但这只是因为FileStream的作者编写了他们的Dispose方法来实现这一目标。

这会导致下一个问题 - 您可以在任务管理器中看到进程的句柄计数,这是一个非常简单的计数器,但您如何测量内存使用情况?请注意,任务管理器中显示的数字远非简单的措施。

答案 3 :(得分:0)

  从我的观察看起来似乎是   程序吃掉的记忆不是   释放了。

这是完全正常的。该程序将挂起一定数量的未使用的内存,如果系统确实需要,它将被释放。

有人可能会认为性能最好的方法是尽可能减少内存使用量,但实际上却是另一种方式。由于拥有大量未使用的内存,计算机根本没有任何好处,因此为了获得最佳性能,应用程序不应该做额外的工作来最小化内存使用量,直到真正需要它为止。

  

如果,Dispose可以释放内存   还有其他指向的对象   它?

是,不......

调用对象上的Dispose不会释放对象本身,但是如果对象包含其他对象,则可以通过Dispose方法释放这些对象。这本身不会释放任何内存,但它会让垃圾收集器在下次运行时执行它。

答案 4 :(得分:0)

如果您已正确实现它,并且您正在释放Dispose()内的所有非托管资源,那么在您释放对该对象的所有引用后,应该收集该对象(或者更好,有资格进行收集)。 / p>

但请注意,您未在示例中处置对象A,该对象也是IDisposable。如果A包含对B的引用,并且您没有处置A,那么这可能会延迟B的收集(如果A有一些非托管的东西,可能会创建对A)的引用。

由于示例中A似乎引用了非托管代码,A应该负责处理它。