[转载].net类的初始化机制,顺序,内存分配

对于类的初始化

类成员的初始化顺序, 举例 ChildClass从ParentClass继承而来

1.  初始化ChildClass的静态字段(按声明顺序)
2.  初始化ChildClass的静态构造函数
3.  初始化ChildClass的实例字段
4.  调用ChildClass的构造函数,并在此中断, 调用ParentClass的构造函数, 导致ParentClass开始初始化
5.  初始化ParentClass的静态字段
6.  初始化ParentClass的静态构造函数
7.  初始化ParentClass的实例字段
8.  调用ParentClass的实例构造函数
9.  ParentClass初始化完毕, 调用ChildClass的构造函数,完成创建

如果多重继承,将按上面方式展开,静态构造函数和静态字段都只构造一次.

如果类没有实例化以前,调用该类的静态方法(字段),会引起类的静态字段实例化, 调用静态构造函数. 以后再实例化此类的时候,不再重新实例化静态字段和静态构造函数

这种初始化顺序是由内存分配机制决定的,如我们调用MyClass myClass = new MyClass(), 其产生对象如下:

1. 计算该类中定义的所有实例字段的size和两个附加对象(type handler(类对象的指针)和syncBlockIndex(指向一块用来管理对象同步的内存))的size并一直递归到object对象,得到其需要分配内存大小, 看剩余内存是否够分配此对象, 不够会导致垃圾回收.
2. 首先构造MyClass的type对象,type对象包括静态字段和方法表,将其分配在托管堆的loader堆上,注意此对象将不会被GC自动回收, 其生命周期是从创建到AppDomain卸载.
3. 构造MyClass的实例字段,构造附加type handler并指向type对象, 构造SyncBlockIndex并指向同步内存. 
4. 调用MyClass构造函数,此时会引起其父类初始化, 父类初始化循环上述过程,直至object对象完成创建, 再返回执行子类构造函数直至MyClass, 创建MyClass完成后, 返回其内存地址, 赋值给MyClass的this,并将其引用传给栈上声明的myClass.

 

class ParentClass
{
      // 静态变量
      public static DisplayClass p_StaticField = new DisplayClass("父类--静态变量");
      // 变量
     public DisplayClass p_Field = new DisplayClass("父类--变量");
     // 静态初始化块
     static ParentClass() { Console.WriteLine("父类--静态初始化块"); }
     // 构造器
     public ParentClass() { Console.WriteLine("父类--构造器"); }
}

class ChildClass : ParentClass
{
     // 静态变量
     public static DisplayClass s_StaticField = new DisplayClass("子类--静态变量");
     // 变量
     public DisplayClass s_Field = new DisplayClass("子类--变量");
     // 静态初始化块
     static ChildClass() { Console.WriteLine("子类--静态初始化块"); }
     // 构造器
     public ChildClass() { Console.WriteLine("子类--构造器"); }
     // 程序入口
    public static void Main()
    {
        new ChildClass();
    }
}

class DisplayClass
{
    public DisplayClass(string message)
   {
       Console.WriteLine(message);
    }
}

 

posted @ 2013-04-09 11:17  骑猪上学  阅读(377)  评论(0编辑  收藏  举报