首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

WinCE线程和内存管理之内存管理 (3)

WinCE线程和内存管理之内存管理 (3)

3、进程地址空间结构

  进程地址空间结构如图2所示。这个图源至MSDN。Windows CE.NET同以前版本的Windows CE操作系统在进程地址空间上有所不同,以前的Windows CE把XIP DLL也加载到进程的32MB地址空间中,而Windows CE.NET把XIP DLL单独加载到Slot 1中,这样对于每个进程来说,它总的地址空间就大了一倍,也就是64MB。这个问题我在讲解进程的时候提到过。

  当一个应用程序启动时,内核为这个程序选择一个空闲的槽(Slot),并且加载所有的代码、资源,并分配堆栈,加载DLL等。当这个进程得到CPU使用权时,它的整个地址空间被内核映射到Slot 0,也就是当前进程使用的地址空间,然后开始运行。图中给出的地址实际上是经过映射到Slot 0之后的结构。从图中可以看出,进程首先加载代码段,因为每个进程最低部64KB作为保留区域,所以代码段从0x0001 0000开始,内核为代码段分配足够的虚拟地址空间后,接着分配空间为只读数据和可读/可写数据,接着分配空间为资源数据,之后分配空间为默认堆和栈。非XIP DLL从进程最高地址向下开始加载。非XIP DLL的加载按如下规则:内核先检查要加载的DLL是否被其它进程加载过,如果加载过,就做一个地址的重定位。这样就避免了整个系统内多次加载相同DLL。如果没有加载过,就按照从槽的高地址到槽的低地址的顺序查找空闲的地址空间。然后分配足够的地址空间用于加载DLL。因为每个进程在执行前都要映射到Slot 0,而且进程使用的所有DLL可能来自不同的槽(Slot),为避免所有使用的DLL在映射到Slot 0中出现地址空间冲突的现象,内核的加载器(Loader)在加载DLL时会查找所有槽中加载的DLL的地址,保证在映射到Slot 0时不会发生地址冲突现象。假如系统内有两个进程,进程A只加载了DLL A,进程B需要加载DLL A和DLL B,那么进程B会留出DLL A的地址空间,然后加载DLL B,也就是说进程B映射到Slot 0时,DLL A的地址空间和DLL B的地址空间是相邻的,不会发生冲突。好在Windows CE下DLL都很小,而且一个应用程序使用的DLL多数是系统的DLL(存在于Slot 1)。所以目前来看进程的地址空间还够用。


继承事业,薪火相传
返回列表