对象生命周期大致经历以下几个阶段
①程序集载入内存,类型装载
②调用new,或类成员(静态成员),触发类静态构造函数(若有)。
③调用new在进行完②之后,触发实例构造函数(若没有自己编写,编译器会创建public默认构造函数,若自己写,无论有参无参,编译器不再创建默认构造函数),
实例构造函数会首先调用父类默认实例构造函数,这是默认行为(生成IL代码时会显示调用),无需显示指定,只有在需要调用父类带参构造函数时,才需显示指定,如:base(x,y,z)。有意思的是,如果父类也有静态构造函数的话,会在此时调用父类静态构造函数。
也就是 : 子类静态构造函数→父类静态构造函数→父类实例构造函数→子类实例构造函数 的顺序。
④调用子类方法,或被作为参数传递,或作为成员构造更大类型,或作为元素转入容器类等。
⑤总之,若对象在应用程序的代码中可以访问该对象,对象就一直存在(活对象,强引用),否则就称为死对象,随时可以被GC回收。(可以对死对象创建弱引用,并且可以使之复活)
⑥在不确定时间点,GC对死对象回收内存。若对象存在Finalize方法,则会被调用(执行终止),若无,则直接被回收。
Finalize被调用的时候会依据继承层次形成调用队列,与构造函数相反,Finalize会先执行本地代码,在执行继承连上层的Finalize(并不保证每个层次都有Finalize方法,若某个层次没有,就调用更上一层的Finalize,最终调用Object.Finalize)。