学习Windows内存管理存疑:RAM分配、虚拟内存时机及加载器镜像加载问题
嘿,我完全懂啃《Windows Internals》时碰到内存管理这块有多头疼——当初我第一次深挖这块的时候也绕了好几个弯!咱们逐个拆解你的问题:
加载器从何处加载镜像?
最常见的来源是本地存储(比如硬盘、SSD上的.exe/.dll文件)。不过加载器也能从其他地方加载:比如网络共享目录里的镜像、内存中的镜像缓冲区(比如某些自解压或打包程序会先把镜像写到内存再加载),甚至是加密后的镜像文件(解密后再加载到进程空间)。但日常场景里,本地磁盘是最主流的来源。操作系统依据什么为进程分配RAM空间?
Windows用的是按需分页机制,物理RAM的分配不是一次性给全的,而是当进程实际访问某个虚拟地址,且该地址对应的物理页不在RAM里时(触发“页错误”),系统才会从可用物理内存池里分配RAM页,或者把暂时不用的页换去分页文件(Pagefile)来腾出空间。具体依据包括:- 进程的实际内存访问需求(比如代码执行到某段、堆/栈申请了空间)
- 系统当前的可用物理内存余量
- 内存管理的置换策略(比如LRU——最近最少使用算法,优先置换不常用的页)
- 进程的优先级(高优先级进程的内存页更不容易被置换出去)
操作系统何时为进程分配虚拟内存?
虚拟内存是进程的地址空间范围,和物理RAM不是一回事。分配时机主要有两个阶段:- 进程创建时:系统会为新进程分配初始的虚拟地址空间,包括镜像映射区、初始栈空间、默认堆空间,还有系统预留的一些区域。
- 进程运行中:当进程调用
VirtualAlloc这类API主动申请内存,或者加载新的DLL、扩展堆/栈时,系统会为它分配额外的虚拟地址空间区域。
注意:分配虚拟内存只是预留了地址范围,此时不一定对应物理RAM,只有当进程访问这些地址时才会触发物理RAM的分配。
加载器首先将镜像加载到RAM还是虚拟内存中?
答案是虚拟内存(进程的虚拟地址空间)。Windows的PE加载器工作时,首先会在目标进程的虚拟地址空间里,根据PE文件的头信息,划分出对应的内存区域(比如代码段、数据段的虚拟地址范围),然后建立虚拟地址到磁盘文件的映射(也就是“内存映射文件”机制)。此时只有少数关键页(比如PE头、启动代码页)会被预加载到物理RAM,其他大部分页都是按需加载——当进程执行到这些页的代码,或者访问这些页的数据时,才会触发页错误,系统再从磁盘把对应的页读入物理RAM。
内容的提问来源于stack exchange,提问作者Misra

