在包含静态字段的非静态类中触发析构函数?

时间:2019-09-14 18:02:31

标签: c# asp.net asp.net-mvc

我想测试何时在类中调用析构函数,当它是一个简单的类时,一切都按预期进行-当我们离开实例的作用域析构函数时。

但是,当我们添加静态字段时,它不会发生。 谁能解释这种情况背后的概念?

IFooClass

对于非静态且具有值的其他字段会发生什么?他们永远不会被清洗吗?

我测试了通过Controller调用析构函数的方法,如下所示

public class Test
{
    ~Test(){}
    private static string StaticField="";
    private float NonStaticField;    
}

当我离开public class HomeController : Controller { // GET: Home public ActionResult Index() { var ts = new Test(); return View(); } } 后删除静态字段时,将调用析构函数。

编辑:调用析构函数有点奇怪,因为它在静态和非静态方法中的行为不同,如果我在静态方法内创建实例并离开范围,则析构函数称为。

2 个答案:

答案 0 :(得分:6)

调用析构函数时没有可预测的要点。内存由garbage collector管理:

  

当以下情况之一发生时,将发生垃圾收集   正确:

     
      
  • 系统的物理内存不足。这可以通过操作系统的内存不足通知或操作系统指示的内存不足来检测   主机。

  •   
  • 托管堆上分配的对象使用的内存超过了可接受的阈值。此阈值是连续的   在过程运行时进行调整。

  •   
  • 将调用GC.Collect方法。在几乎所有情况下,您不必调用此方法,因为垃圾收集器会运行   不断地。此方法主要用于特殊情况和   测试。

  •   

所以通常您对这种情况何时发生并不感兴趣。为了亲自了解,我尝试用一​​个简单的测试程序来重复您的实验。创建无静态字段的测试类的测试函数被多次调用。程序完成后,所有创建的实例才最终确定并释放。

如果这很重要,并且您想控制实例完成的时间,则应该实现IDisposable接口并使用using statement

答案 1 :(得分:3)

我认为根据Microsoft的文章,我终于发现了幕后发生的事情, 垃圾收集器将这些对象视为三代之一, 第0代,第1代,第2代。 它暗含了

  

堆被组织成几代,因此它可以处理长寿和   短暂的对象。垃圾收集主要发生在   回收通常只占一小部分的短寿命物体   堆的一部分

     

生成2。此生成包含寿命很长的对象。一个例子   寿命很长的对象是服务器应用程序中的一个对象   包含在整个过程中处于活动状态的静态数据。

和属于第二代类别的对象不会立即处置, 当然,Web应用程序中的垃圾回收器行为不同于Windows应用程序。 确定垃圾收集器何时执行其工作,我们应该了解latency

  

等待时间是指垃圾收集器入侵您的时间   应用

,Web应用程序的默认延迟模式为Interactive

  

启用垃圾回收并发并回收对象,而   应用程序正在运行。这是垃圾的默认模式   在工作站上收集,并且不如批处理那么麻烦。它   在响应能力和吞吐量之间取得平衡。此模式等效于   并发工作站上的垃圾回收。

我非常确定,这是一个涉及广泛的话题,需要准确考虑, 您可以使用下面的链接阅读有关垃圾收集的更多信息

Fundamentals of garbage collection

Garbage Collection

Latency Mode