一 地址空间
1. 地址空间
一个程序最大的寻址范围。对于Win32操作系统,最大的寻址范围为2的32次方。 2. 地址空间的划分
通常情况下 2.1 用户空间 地址范围:0 - 0x7FFFFFFF(2G) 运行应用程序的代码、数据等。 2.1.1 空指针区(NULL 区) 地址范围 0 - 0x0000FFFF 2.1.2 用户区 地址范围 0x0001000 - 0x7FFEFFFF 2.1.3 64K禁入区 地址范围 0x7FFEFFFF - 0x7FFFFFFF 2.2 内核空间 地址范围:0x80000000 - 0xFFFFFFFF 系统使用,运行驱动、内核的数据和代码。 二 地址映射 1. 内存区域 区域指一段连续的地址空间,区域的大小和CPU的粒度相关。目前都是以64K粒度存在。 地址的对其方式是以64K为边界。 区域状态: 1)保留 - 空闲的, 可以被使用 2)私有 - 已经被占有, 但是还未使用 3)映像 - 程序的代码使用 4)映射 - 程序的数据使用 2. 物理内存 实际可以使用的物理存储器 3. 虚拟内存 使用硬盘空间作为内存扩展,也可以当做物理内存使用。 4. 内存页 操作系统使用内存页的方式管理物理内存和虚拟内存。 通常情况下,内存页的大小为4K 或者8K。 没给内存页具有自己的状态,例如:只读,可写,可执行 5. 页目表 用于管理内存页的表。 页目 - 页表 - 内存页 - 页表 - 页表 指针 31 ----22 21--------12 11--------- 0
页目 页表 偏移量
6.地址空间的访问
6.1 地址空间已经存在映射好的物理内存,直接使用。
6.2 系统去虚拟内存中,查找对应的内存页。如果未找到,体统返回错误。
6.3 系统将虚拟内存的内存页切换到物理当中。
6.4 返回实际物理内存地址,使用数据。
7. 内存的使用
7.1 虚拟内存使用(内存使用方式)
适合大内存分配使用。一般情况下如果分配的内存大于1M,应该使用虚拟内存分配方式。
7.2 堆内存
适合小内存分配使用。一般情况下对于小于1M的内存分配使用。例如malloc/new。
7.3 堆栈内存
系统维护的内存区。
三 虚拟分配
1. 虚拟内存
常用于大内存分配,分配速度快,可以根据需要制定分配方式。
2. 虚拟内存的使用
2.1 分配内存
LPVOID WINAPI VirtualAlloc( _In_opt_ LPVOID lpAddress, //NULL或者用于提交的内存地址 _In_ SIZE_T dwSize, //分配的大小,一般是页的倍数 _In_ DWORD flAllocationType,//分配的方式 _In_ DWORD flProtect //内存访问方式 );分配的空间小于用户区间(2G)
2.2 提交内存
VirtualAlloc 使用MEM_COMMIT方式
2.3 使用内存
2.4 释放内存
VirtualFree
void Virtual() { //地址分配 char * pszBuff =(char *) VirtualAlloc(NULL, 1024 * 1024 ,MEM_RESERVE, PAGE_READWRITE) ; printf("RESREVE: %p\n", pszBuff) ; //内存提交 VirtualAlloc(pszBuff, 1024 * 1024, MEM_COMMIT, PAGE_READWRITE) ; printf("COMMIT: %p\n", pszBuff) ; strcpy(pszBuff, "hello Virtual") ; printf("%s\n" ,pszBuff) ; getch() ; VirtualFree(pszBuff, 1024 * 1024 * 1024, MEM_RELEASE) ; }
3.内存信息GlobalMemoryState
三 堆内存
1. 对内存的特点
一般分配小数据内存,一般小于1M数据使用堆内存分配。
一般程序执行后,会有一个默认堆,这个堆大小一般为1M。
一个程序可以有多个堆存在。拖过堆内存管理器来管理堆中的内存。
内存分配速度比VirtualAlloc慢。
2. 堆内存的使用
2.1 创建堆
HeapCreate
2.2 分配内存
HeapAlloc
2.3 使用内存
2.4 释放内存
HeapFree
2.5 释放堆
HeapDestory
3. malloc / HeapAlloc / VirtualAlloc
malloc 内部调用 HeapAlloc。
HeapAlloc 内部调用Vitrualloc。
malloc分配内存:例如有100个字节。
| 内存头 | 100字节 |
所有使用malloc分配的内存,会使用这个内存头构成一个双向链表。
4.堆的信息
GetProcessHeap 当前进程默认堆的句柄
GetProcessHeaps 当前进程所有堆的句柄
四 堆栈内存
堆栈都是小数据的使用,系统维护,栈的大小一般在1M左右。
例如,Windows下可以使用_alloca函数从栈上分配内存。
五 内存映射文件
1. 内存映射文件
可以将文件映射成内存,我没可以像使用内存一样使用文件。
2. 内存映射文件的使用
2.1 创建或打开一个文件
CreateFile
2.2 创建一个内存映射文件
CreateFileMapping
2.3 将内存映射文件映射成内存地址
MapViewOfFile
2.4 使用内存
2.5 卸载映射
UnmapViewOfFile
2.6 关闭内存映射文件
CloseHandle
2.7 文件关闭
CloseHandle