c#基础知识复习

基础知识1: 堆栈(书名:c#从现象到本质)

堆栈(heap stack)

  1. 堆可以分为托管堆和非托管堆,CLR管理托管堆和栈的垃圾回收。非托管堆由我们自己管理回收。
  2. 堆基于进程,属于进程空间的一部分。托管堆主要分为以下几个部分:
    1. GC堆(GC heap)
    2. 三个程序域
  3. 栈基于线程

三个程序域

系统域(开发者无法操作)
共享域(开发者无法操作)
应用程序域(AppDomain的一个实例) 每个AppDomain有自己的加载堆

加载堆(loader heap)

存在于每个程序域中,存放CLR的类型系统和用户自定义的类型对象,不同域的加载堆存放的对象不同。 AppDomain加载堆也存放静态对象,由于静态对象是全局的,不会成为垃圾,所以不受GC管辖。加载堆分为高频堆(32k),低频堆(8k)。比如值类型(或者引用类型)的静态变量就分配在加载堆上,所以值类型不一定分配在栈或托管堆上

GC堆(GC heap) 简单介绍

垃圾收集器的处理对象。分为0,1,2代,代越高越大。2代中有个特殊部分 大对象堆(large object heap) 它存放超过85k大小的对象。 // 小对象堆(SOH)

方法表指针(method table pointer) / 类型对象指针(TypeHandle)和同步块索引(synchronization block index)

同步块索引是类的标配,它位于类在堆上定义的开头-4(或-8 注释:32位 64位内存页大小) 至 0字节。 CLR管理一个同步块数组,共32、64多功能结构其中前6位提示访问者自身为0 , 1代表不同的功能, 比如线程同步,当对象被线程访问后会判断索引值是否为特殊值,如果否则不能操作这个实例,如果是则会在同步数组中分配一个同步块,并将此索引值写入实例的索引值。

方法表指针又称类型对象指针,类型对象由CLR在加载堆中创建,类型对象中存放了静态字段和方法表,所以反射获取到的类型就是它类型对象,并且指向同一个

内存对齐

消除排列顺序的不同带来的额外的内存页消耗
32位
bit
int
bit
这3个CLR会把它换成int bit bit

值类型引用类型

值类型一定是密封的
值类型不一定分配在栈上

  1. 值类型含有引用类型,会分配到托管堆上
  2. 值类型是静态变量分配到加载堆
  3. 局部变量升级为密封类(闭包)

装箱拆箱

装箱把值类型转为object或者实现的接口

  1. 在堆中申请内存
  2. 再加上类型对象和同步块索引
  3. 将值类型字段拷贝到新分配的内存上
  4. 返回对象的内存地址
原文地址:https://www.cnblogs.com/caiyangcc/p/15164687.html