垃圾收集器如何处理静态类使用的类型对象?

时间:2013-12-18 15:50:16

标签: c# garbage-collection clr

假设我有以下课程:

 public class Class1
 {
      private Class2 _class2;

      public void SomeMethod() 
      { 
           _class2 = new Class2();               
      }
 }

这是我对调用var instance = new Class1()时会发生什么的理解:

  • 如果它尚不存在,则会在堆上为Class1
  • 创建一个新的类型对象
  • instance在堆上创建,其类型对象指针指向Class1类型对象

问题1 :是否会为Class2创建一个类型对象,因为Class1引用它,即使我还没有实例化它(假设它还不存在)当然)?

现在假设我有以下静态类

 public static class StaticClass
 {
      private static NormalClass _normalClass = new NormalClass();
      public static void SomeMethod() 
      { 
           // Does something using _normalClass 
      }
 }

当我调用SomeMethod()时,会在堆上创建StaticClass类型对象。

_normalClass也已创建,NormalClass类型对象也是如此。

我知道StaticClass Type对象永远不会被垃圾收集。任何因为它持有_normalClass的引用,也不会。

问题2 :是否收集了Type Objects垃圾?如果是这样,NormalClass的类型对象是否可以用于垃圾收集?在NormalClass内引用的任何内容的类型对象怎么样?

当我创建一个看似无辜的静态类时,我是否可能用一个大型“链”类型对象来填充堆,这些类型对象永远不会被垃圾回收?

1 个答案:

答案 0 :(得分:0)

好的,您对CLR如何工作的想法是错误的。如果您想完全理解它是如何工作的,请参阅.NET Internals上的这篇文章:

http://msdn.microsoft.com/en-us/magazine/cc163791.aspx#S7

首先,让我们理解正确:

  1. 除非您使用反射,否则不会在堆上创建任何类型对象。
  2. 分配对象时,它有一个“TypeHandle”,指向有关该类型的信息。
  3. 现在,问题:

    答案1:

    没有。当实例化时,堆上的Class1会发生内存分配。作为引用类型的Class2获取引用指针。因此,分配用于保持引用指针的存储器。周期。

    当实例化Class2时,实际存储的内存(基于字段大小)在堆中分配。

    答案2:

    是的,但它们不是你所认为的那样。

    _normalClass是否可以被垃圾收集?是。如果在某些时候将其设置为null,则会在GC运行时收集它。

相关问题