.NET面试准备(三)GC与内存管理

一 、创建对象及生命周期

要使用这些资源,必须为代表资源的类型分配内存,进程初始化时,CLR划出一个地址区域作为托管堆,NextObjPtr指针指向下一个对象在托管堆中的分配位置,步骤如下:

1.new一个对象,调用IL指令newobject,为对象分配内存

  • 对象大小估算:计算对象的字段所需的字节数,加上对象开销所需的字节数(类型对象指针,同步块索引)
  • 检查托管堆内存:
    • 内存充足,在NextObjptr指针指向的地址放入对象,为构造器的this参数传递内存地址
    • 内存不足,触发CG回收

2.初始化内存,实例构造器设置初始状态
3.使用资源
4.清理资源
5.释放内存(GC垃圾回收)

创建一个新对象的流程
在这里插入图片描述

二、GC垃圾回收

1 引用跟踪算法:判断对象是否属于垃圾
2 垃圾回收的基本流程:

  • 标记:暂停进程中所有线程,CLR遍历堆中所有对象,将同步块索引字段标记为0(不可达对象),检查所有活动根,如果根引用了对象,标记该对象的同步块索引为1(可达对象)。
  • 清除:清除所有不可达对象
  • 压缩:碎片整理,把剩下的对象转移到一个连续的内存,把root和指针的地址修改为移动后的地址

3 垃圾回收触发条件

  • 内存不足时(0代对象已满)
  • 显示调用System.GC
  • windows报告内存不足,CLR强制垃圾回收释放死对象
  • CLR正在卸载appDomain
  • CLR正在关闭

三、关于代龄

CLR的GC是居于代的垃圾回收器,分代回收速度快于回收整个堆。
分代算法的假设条件

  • 对象越新,生存期越短
  • 对象越老,生存期越长
  • 回收堆的一部分,速度快于回收整个堆
  • 新创建的对象之间关联度较高

三个 代龄区域

  • 0代:新添加到堆的对象,垃圾回收从未发生过
  • 1代:0代满了,会触发垃圾回收,0代垃圾回收后,剩下的对象会被搬到1代
  • 2代:当0代 1代满了,会触发0代 1代的垃圾回收,第0代升为1代,第1代升为2代

大对象

  • 大于等于85000字节的对象成为大对象
  • 大对象不在小对象的地址空间分配,而在进程地址空间的其他地方分配
  • 大对象总是第2代,所以需要长时间存活的资源创建大对象

四、非托管资源回收

通过Finalize()和Dispose()。
Finalize():
Dispose():

参考

猜你喜欢

转载自blog.csdn.net/hhhhhhenrik/article/details/93404182