windows底层内存管理技术

1.1. 物理地址

在物理存储器上的内存地址,一般由内核管理,应用程序无法直接得到。

1.2. 虚拟地址

在进程私有空间中的地址,即应用程序指针所指向的地址值。

1.3. 寻址空间

进程所能够范围的地址空间范围,跟指针的位数有关,指针的位数取决于cpu字长,32位指针的地址空间范围为4GB,64位指针的地址空间范围为1 6 E B。

2. windows内存结构

2.1. 虚拟地址空间的管理

对于32位多任务的windows操作系统来说,每个进程都在自己的私有地址空间(虚拟地址空间)运行,因此当进程中的一个线程正在运行时,该线程可以访问只属于它的进程的内存。属于所有其他进程的内存则隐藏着,并且不能被正在运行的线程访问。

在win2k中,属于内核的内存也是隐藏的,正在运行的线程无法访问。这意味着线程不能直接访问内核的数据。如果要想访问内核数据,则必须通过系统调用(系统win32 api)来操作,否则会引发一个内存错误异常。

Win98中,属于操作系统的内存是不隐藏的,正在运行的线程可以访问。因此,正在运行的线程常常可以访问操作系统的数据,也可以破坏操作系统(从而有可能导致操作系统崩溃)。

在Win98中,一个进程的线程不可能访问属于另一个进程的内存,与win2k相同。

建议无论在win98还是win2k中,都采用系统调用来访问内核(操作系统内存)。

2.2. 虚拟地址空间的划分

虽然32位的应用程序理论上可以访问4GB的地址空间,但是真正可以使用的地址空间并没有那么多。

每个进程的虚拟地址空间都要划分成各个分区。地址空间的分区是根据操作系统的基本实现方法来进行的。不同的Windows内核,其分区也略有不同。winxp的内存结构与win2k相同。

进程的地址空间分区表

分区

32位Windows 2000(x86和Alpha处理器)

32位Windows 2000(x86w/3GB用户方式)

64位Windows 2000(Alpha和IA-64处理器)

Windows 98

N U L L指针分配的分区

0 x 0 0 0 0 0 0 0 0 0 x 0 0 0 0 F F F F

0 x 0 0 0 0 0 0 0 0 0 x 0 0 0 0 F F F F

0x00000000 00000000 0x00000000 0000FFFF

0 x 0 0 0 0 0 0 0 0 0 x 0 0 0 0 0 F F F

DOS/16位Windows应用程序兼容分区

0 x 0 0 0 0 0 1 0 0 0 0 x 0 0 3 F F F F F

用户方式

0 x 0 0 0 1 0 0 0 0 0 x 7 F F E F F F F

0 x 0 0 0 1 0 0 0 0 0 x B F F E F F F F F

0x00000000 00010000 0x000003FF FFFEFFFF

0 x 0 0 4 0 0 0 0 0 0 x 7 F F F F F F F

64-KB

0 x 7 F F F 0 0 0 0

0 x B F F F 0 0 0 0

0 x 0 0 0 0 0 3 F F F F F F 0 0 0 0

禁止进入

0 x 7 F F F F F F F

0 x B F F F F F F F

0 x 0 0 0 0 0 3 F F F F F F F F F F

共享的MMF分区

0 x 8 0 0 0 0 0 0 0

文件(MMF)内核方式

0 x 8 0 0 0 0 0 0 0 0 0 x F F F F F F F F

0 x C 0 0 0 0 0 0 0 0 x F F F F F F F F

0x00000400 00000000 0xFFFFFFFFF FFFFFFF

0 x B F F F F F F F 0 x C 0 0 0 0 0 0 0 0 x F F F F F F F F

3 2位Windows 2000的内核与6 4位Windows 2000的内核拥有大体相同的分区,差别在于分区的大小和位置有所不同。另一方面,可以看到Windows 98下的分区有着很大的不同。

NULL指针分配的分区:为了帮助程序员掌握N U L L指针的分配情况。如果你的进程中的线程试图读取该分区的地址空间的数据,或者将数据写入该分区的地址空间,那么C P U就会引发一个访问违规。保护这个分区是极其有用的,它可以帮助你发现N U L L指针的分配情况。一般的c/c++编译器都把NULL设置为0,落在这个分区中。

MS-DOS/16Windows应用程序兼容分区(仅适用Win98):进程地址空间的这个4MB分区是Windows 98需要的,目的是维护MS - DOS应用程序与16位应用程序之间的兼容性。不应该试图从32位应用程序来读取该分区的数据,或者将数据写入该分区。在理想的情况下,如果进程中的线程访问该内存, CPU应该产生一个访问违规,但是由于技术上的原因, Microsoft无法保护这个4MB的地址空间。

在Windows 2000中,16位MS-DOS与16位Windows应用程序是在它们自己的地址空间(其实是在虚拟机中)中运行的,32位应用程序不会对它们产生任何影响。

16位DOS程序的虚拟机就是cmd,16位windows程序使用的是系统虚拟机。

用户方式分区:这个分区是进程的私有(非共享)地址空间所在的地方。

在Windows 2000中,所有的. e x e和DLL模块均加载这个分区。每个进程可以将这些D L L加载到该分区的不同地址中(不过这种可能性很小)。系统还可以在这个分区中映射该进程可以访问的所有内存映射文件。

在Windows 98中,主要的Win32系统DLL(Kernel32.dll,AdvAPI32.dll,User32.dll和GDI32.dll)均加载共享内存映射文件分区中。. e x e和所有其他D L L模块则加载到这个用户方式分区中。多个进程的共享D L L均位于相同的虚拟地址中,但是其他DLL可以将这些D L L加载到用户方式分区的不同地址中(不过这种可能性不大)。另外,在Windows 98中,用户方式分区中决不会出现内存映射文件。

在32位windows中,用户分区的最大寻址空间大约为2G,内核寻址空间为3G。M i crosof t允许x 8 6的Windows 2000 Advanced Server版本和Windows 2000 Data Center版本将用户方式分区扩大为3 G B,内核分区压缩为1G。若要使所有进程都能够使用3 G B用户方式分区和1 G B内核方式分区,必须将/ 3 G B开关附加到系统的BOOT. INI文件的有关项目中。

在x86w/3GB和64位的windows中,若要使用2GB以上的用户空间,该应用程序必须使用/ LARGEADDRESSAWARE 链接开关来创建。

64KB禁止进入的分区(适用于win2k):这个位于用户方式分区上面的64 KB分区是禁止进入的,访问该分区中的内存的任何企图均将导致访问违规。

共享的MMF分区(适用于win98):存放系统DLL、进程共享数据和内存映射文件。

内核方式分区:存放内核代码。用于线程调度、内存管理、文件系统支持、网络支持和所有设备驱动程序的代码全部在这个分区加载。驻留在这个分区中的一切均可被所有进程共享。

在Windows 2000中,这些组件是完全受到保护的。如果你试图访问该分区中的内存地址,你的线程将会产生访问违规,导致系统向用户显示一个消息框,并关闭你的应用程序。

在Windows 98中该分区中的数据是不受保护的。任何应用程序都可以从该分区读取数据,也可以写入数据,因此有可能破坏操作系统。

2.3. 地址空间的区域

当进程被创建并被赋予它的地址空间时&#

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值