商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > .NET Core内存结构体系(Windows环境)底层原理解析

.NET Core内存结构体系(Windows环境)底层原理解析

  发布于2026-07-23 阅读(0)

扫一扫,手机访问

物理内存与虚拟内存物理内存

先说两个基础概念,搞懂了它们,后面的东西才能串起来。

  • 物理内存(Physical Memory)

这没什么好说的,就是计算机硬件里实实在在的RAM,比如你插的那根DDR5内存条。它直接通过总线跟CPU打交道,专门用来临时存着正在运行的程序和数据。

  • 虚拟内存(Virtual Memory)

这个就有点意思了。它是操作系统凭空“编”出来的一层抽象内存,把物理内存和磁盘空间(比如页面文件或者交换分区)搅在一起,给每个程序都提供一段连续、独立的内存空间。说白了,你写程序的时候,根本不用管数据到底在内存条上,还是在硬盘的某个角落里,只需要跟虚拟内存地址打交道就行。

用户只需要与虚拟内存地址打交道,而无需关心数据到底分配在哪里

.NET Core内存结构体系(Windows环境)底层原理解析

眼见为实

.NET Core内存结构体系(Windows环境)底层原理解析

物理页4K对齐

在Windows系统里,一切内存操作都以4K为最小单位,这个单位就叫物理页。操作系统分配内存时,永远是4K的整数倍。举个例子,你申请1K,它给你分配4K;你申请5K,它就给你分配8K。就是这么粗暴,但高效。

眼见为实

void page4k() {for (int i = 0; i < 200; i++) {//1k 的占用LPVOID ptr = VirtualAlloc(NULL, 1024 * 1, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);printf("i=%d, 1k, address:%#0.8x \n", i + 1, ptr);}for (int i = 200; i < 400; i++) {//5k 的占用LPVOID ptr = VirtualAlloc(NULL, 1024 * 5, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);printf("i=%d, 5k, address:%#0.8x \n", i + 1, ptr);}getchar();}

申请1k分配4k

.NET Core内存结构体系(Windows环境)底层原理解析

申请5k分配8k

.NET Core内存结构体系(Windows环境)底层原理解析

物理内存与虚拟内存如何映射?

虚拟地址和物理地址之间怎么搭上线?Windows用了二叉树结构(5层)来实现这种高效映射。这层映射关系,是整个内存管理的核心。

举个例子,假设有个32bit的内存地址:0x77b01a42,它的二进制是:01110,11110,11000,00001,101001000010。这串数字怎么用呢?

.NET Core内存结构体系(Windows环境)底层原理解析

.NET Core内存结构体系(Windows环境)底层原理解析

  • 前20位用来构建页表树,实现物理页的高效映射
  • 后12位映射物理页内的偏移量

操作系统以4K为一个单位对内存进行分组。4G内存有多少个物理页?算一下:1024*1024*1024*4/(4/1024) = 1048576个。上百万个物理页,如果没有这颗5层二叉树去索引,效率简直不敢想象。

眼见为实:以notepad为例

任务管理:

Windbg:

.NET Core内存结构体系(Windows环境)底层原理解析

看到没?同样一个notepad,任务管理器显示占用44.6MB内存,而Windbg显示占用489.531MB内存。为什么差距这么大?原因在于显示逻辑不同:任务管理器显示的是Private WorkingSet,这是物理内存,也就是内存条上的内存;而Windbg显示的是Commit,指的是虚拟内存地址,这包括内存条上的内存,pagefile,image三种。

眼见为实:可视化观察 虚拟地址 => 物理地址

用Windbg进入内核态,这很重要。大家可以猜猜为什么非得进内核态。

随便找一个字符串的内存地址

.NET Core内存结构体系(Windows环境)底层原理解析

  • 使用dp观察虚拟地址
  • 使用!vtop 观察映射信息
  • 使用!db观察物理地址

.NET Core内存结构体系(Windows环境)底层原理解析

眼见为实:空指针区与用户态区

.NET Core内存结构体系(Windows环境)底层原理解析

Windows和Linux在默认情况下,都会开启ASLR(地址空间布局随机化)。如果想把这块研究透,需要关闭这个技术才能复现。ASLR是一种针对缓冲区溢出攻击等内存攻击技术而设计的安全特性。没有ASLR时,程序加载到内存中的位置是固定的,攻击者可以预测模块的加载地址,从而构造恶意代码。启用ASLR后,操作系统在每次启动程序时会随机化内存布局,包括可执行文件、动态链接库、堆、栈等的加载地址,大大增加攻击难度。

Reserved与Commit

这两个概念,是理解虚拟内存分配的关键。

  • Reserved

在虚拟地址上申请一段内存空间,此时操作系统会同步创建页表树,但并未映射到物理内存。这时候你要是对这块虚拟内存进行读写,等着你的就是异常。

  • Commit

页表树调配真实的物理内存,只有这一步完成后,才能正常写入数据。

眼见为实: Reserved

void  mem_reserved() {LPVOID ptr = VirtualAlloc(NULL, 4 * 1024, MEM_RESERVE, PAGE_READWRITE);*(int*)(ptr) = 10;  //在首地址上写入内容。printf("num=%d", *(int*)ptr);}

.NET Core内存结构体系(Windows环境)底层原理解析

眼见为实: Commit

void  mem_commit() {LPVOID ptr = VirtualAlloc(NULL, 4 * 1024, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);*(int*)(ptr) = 10;  //在首地址上写入内容。printf("num=%d", *(int*)ptr);}

.NET Core内存结构体系(Windows环境)底层原理解析

NT堆

NT堆是Windows NT内核引入的内存管理组件,主要负责进程内的堆内存分配与释放。在Windows系统里,进程使用NT堆来动态分配和管理内存,比如程序中的malloc()(C语言)、new(C++)等函数,底层通常就依赖NT堆机制。

前面说到,VirtualAlloc方法会一次性分配64K整数倍的内存段,内部对象按4K的内存页对齐。如果让应用程序直接操作VirtualAlloc,难免会造成大量内存浪费。为了提高内存性能与使用效率,Windows又提供了一层抽象,以提供更细颗粒度的内存管理,它就是NT堆

  • 在32bit平台上:8byte为一个分配粒度
  • 在64bit平台上:16byte为一个分配粒度

.NET Core内存结构体系(Windows环境)底层原理解析

  • CRT堆:C运行时使用的堆,默认是对NT堆的简单封装
  • 托管堆:用作特殊用途的,自行实现的一套内存池管理机制,比如GC堆

从图中可以看出,用不用NT堆,完全取决于程序员自己。你可以绕过NT堆,直接使用VirtualAlloc来分配内存,只要你能接受内存浪费。

眼见为实:GC堆,底层使用VirtualAlloc分配内存

static void Main(string[] args)        {            var rand = new Random();            List list = new List();            for (int i = 0; i < 100000; i++)            {                var str = string.Join(",", Enumerable.Range(0, rand.Next(1, 1000)));                list.Add(str);                Console.WriteLine($"i={i},length={str.Length}");            }            Console.ReadLine();        }

在bp KERNELBASE!VirtualAlloc 下断点

.NET Core内存结构体系(Windows环境)底层原理解析

.NET Core内存结构体系(Windows环境)底层原理解析

眼见为实:CRT堆/NT堆,底层使用VirtualAlloc分配内存

​#include #include void crt_c() {for (int i = 0; i < 10000000; i++) {int* ptr = (int*)malloc(sizeof(int) * 1000);*(ptr) = 10;printf("第 %d 次分配 \n", i);}}​

在 bp ntdll!NtAllocateVirtualMemory 下断点

.NET Core内存结构体系(Windows环境)底层原理解析

本文转载于:https://www.jb51.net/aspnet/335615i75.htm 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注