Windows内存管理学习

一. 关于内存管理 1.1 虚拟地址空间 每个进程的虚拟地址是私有的并且无法被其他进程访问(除非共享)。系统为每个进程维护一个页表用来将虚拟地址变为物理地址。 虚拟地址空间的大小受到不同的cpu架构,不同的windows操作系统和LargeAddressAware与 4GT 设置影响。 1.1.1 32位 ——4GT设置 在 32 位系统中,虚拟地址是 4 GB(2³² = 4 GB): 默认情况:用户程序最多只能访问 2 GB 的虚拟地址 启用 4GT 后分布变成: 这样用户态程序能用更多虚拟内存(适合数据库、游戏服务器等),但内核空间只有 1 GB,系统缓存和驱动可用空间变少。 启用方式 Windows Vista 及更高版本:bcdedit /set increaseuserva <值> Windows Server 2003 及更早:在 Boot.ini 中添加: /3GB 或者更细调 /USERVA=2560 让程序识别 4GT —— /LARGEADDRESSAWARE 编译时加: link /LARGEADDRESSAWARE myapp.obj 没加此标志 → 即使系统启用了 4GT,程序仍只能看到 2 GB。 加了 → 在 /3GB 系统上可看到 3 GB,在 64 位系统上甚至可用 4 GB。 ...

October 14, 2025 · 1495 words

Linux堆学习

前言 要深入了解linux的内存管理,对于堆栈的认识是必不可少的。相对于栈来说,堆相对来说更加复杂。所以在看了大量文章以后,决定对堆中的一些基本概念总结一下,希望师傅们指教。 本文只讨论单线程,64位,glibc2.41版本 (等后续有空更新 堆的定义 ctf-wiki中是这样描述的 在程序运行过程中,堆可以提供动态分配的内存,允许程序申请大小未知的内存。 堆其实就是程序虚拟地址空间的一块连续的线性区域,它由低地址向高地址方向增长。 我们一般称管理堆的那部分程序为堆管理器。 堆主要有两个作用: 响应用户的申请内存请求,向操作系统申请内存,然后将其返回给用户程序。 管理用户所释放的内存 malloc 流程图 free流程图 堆的利用 这个版本的glibc在向上合并的时候并没有把当前块的控制信息消除,所以可以double-free #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <stdlib.h> #define te int main() { int i = 0; void *x[7]; for(i; i<7;i++){ x[i] = malloc(0x100); } void *p1; p1 = malloc(0x200); void *p2; p2 = malloc(0x200); malloc(10); // 防止和av->top 合并 for(i = 0; i< 7 ;i++){ free(x[i]); } // 填满tcache_bins free(p1); // 放入small_bins free(p2); // 触发合并刚好进入unsorted_bins,并且没有清空控制信息 malloc(0x200); free(p2); // double-free getchar(); return 0; }

September 26, 2025 · 80 words