ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

01-03-认知篇-C#内存模型深度解析

01-03-认知篇-C#内存模型深度解析 C# 内存模型深度解析篇章01-认知篇 |阅读时间约 40 分钟 |前置知识了解 C# 基本语法一、引言GC 管理的对象在 C# 的托管堆上分配。但并非所有数据都在托管堆上——值类型可以在栈上分配引用类型的引用在栈上但对象在堆上。理解 C# 内存模型的每个细节是准确分析 GC 行为的前提。二、托管堆托管堆是 GC 管理的内存区域所有引用类型对象class 实例、数组、委托、字符串都分配在此。托管堆布局 ┌────────────────────────────────────────────┐ │ Gen 0 │ Gen 1 │ Gen 2 │ LOH │ │ (新对象) │ (晋升) │ (长期存活) │ (大对象) │ └────────────────────────────────────────────┘关键特征堆上的对象通过可达性分析判断生死对象被回收后内存可能被压缩移动对象分配在堆上的对象具有不确定的生命周期三、栈每个线程有独立的栈存储局部变量和方法参数函数调用的返回地址值类型实例当作为局部变量时栈的自动管理特性分配快只需移动栈指针SP释放快方法返回时 SP 恢复不产生 GC栈上的数据随方法返回自动释放void Example() { int x 42; // x 在栈上不经过 GC MyClass obj new(); // obj 引用在栈上对象在堆上 // x 随方法返回自动释放不产生 GC // obj 指向的堆对象由 GC 管理 }四、值类型与引用类型维度值类型struct引用类型class存储位置栈局部变量或堆装箱/字段堆赋值语义复制整个数据复制引用指针GC 管理不直接管理栈上GC 标记-清扫默认传递传值复制传引用指针复制可为 null可Nullable可多态不支持无虚函数表指针支持五、对象头与内存布局每个托管对象从对象头开始然后是实际数据┌─────────────────┐ │ Object Header │ 8-16 字节同步块索引 方法表指针 ├─────────────────┤ │ 字段 1 │ │ 字段 2 │ │ ... │ 实际数据 │ 字段 N │ ├─────────────────┤ │ 填充 (Padding) │ 对齐到 4/8 字节 └─────────────────┘对象头的开销32 位8 字节SyncBlockIndex 4B MethodTable* 4B64 位16 字节SyncBlockIndex 4B 填充 4B MethodTable* 8B六、GC RootsGC 从一组称为 Roots 的引用出发遍历对象图Roots 类型内容数量级栈变量每个线程栈上的对象引用数百静态变量全局静态字段数百到数千寄存器CPU 寄存器中的引用数十GC HandleGCHandle.Alloc 固定的对象数百Finalizer 队列待执行 Finalizer 的对象数十七、总结C# 内存模型的核心在于栈引用 → 堆对象的架构。栈上的值类型自动释放不经过 GC堆上的引用类型由 GC 管理。理解这个基础架构是正确分析 GC 分配来源和优化策略的前提。八、内存模型对 GC 性能的影响内存区域GC 管理分配速度回收方式性能影响托管堆GC 标记-清扫中(bump ptr)GC 周期回收GC 暂停栈自动(SP移动)极快(1指令)函数返回零暂停LOHGC 特殊管理慢(空闲链表)Gen2 GC长暂停PinnedGC 手动正常阻碍压缩增加碎片
返回列表