VC++技术内幕(第四版)笔记(第9章)

第九章:Win32内存管理


1,一个程序就是一个EXE文件。Windows中,一旦一个程序被启动的,系统为其创建一个进程。一个进程拥有自己的内存,文件句柄,和其它的系统资源。如果连续两次启动同一个程序,系统为其创建两个独立的进程并发运行(并发:微观交替串行,宏观并行)。
说明:
1)一个进程(如Windows Wxplorer)可能有多个主窗口(每一个窗口由一个线程支持),也可能没有任何窗口。
2)进程拥有自己“私有”4GB虚拟地址空间。
3)每个进程内存空间包含各种各样的内容(具体参见169页): 程序EXE镜像,程序中装入的非系统的DLL(包括MFC DLL),程序的全局数据,程序的堆栈,动态分配内存(包括Windows和C运行库堆),内存映射文件,进程之间共享的内存块,特定执行线程的局部内存,所有系统内存模块(包括虚拟内存表),Windows核心、执行过程及DLL(是OS的一部分)。


2,Windows 95进程地址空间:
WIN95中,只有底下的2GB(0-0x7FFFFFFF)地址空间是进程私有的。其中最底下的4MB禁止访问。堆栈、堆和可读写的全局内存,及其应用程序的EXE和DLL文件都被映射底下的2GB地址上。
上面的2GB地址空间对所有的进程都一样的,由所有的进程共享。
WIN95核心、执行过程、虚拟设备驱动程序和文件系统代码,以及一些重要的表(如:页表),都被映射到最上面的1GB(0xC0000000-0xFFFFFFFF)地址空间。
Windows DLL和内存映射文件位于0x80000000-0xBFFFFFFF地址空间。
安全性说明:
1)所有的EXE和DLL代码都有只读标记,因而可以映射到几个不同的进程中。
2)一个进程不可能改写另一个进程私有的2GB地址空间内容。
3)进程地址空间中最上面的2GB由于是共享的,很容易受攻击毁坏。如:错误进程毁坏这一区域重要的系统表,进程的内存映射文件被其它进程弄乱。

3,Windows NT进程地址空间:
WIN NT中,进程只能访问它最底下的2GB地址空间(除最底和最高的64K是不能访问)即:0x00010000-0x7FFEFFFF。
EXE、应用程序的DLL 和 Windows的DLL、以及内存映射文件都驻留在0x00010000-0x7FFEFFFF地址空间中。
Windows NT内核、可执行程序和设备驱动程序都被映射到上面的2GB空间中,完全受保护,可以避免错误程序的侵入。
安全性分析:
1)进程内存地址空间上2GB空间,完全受保护,可以避免错误程序的侵入破坏其中内容。
2)内存映射文件更安全,如果不知道文件的名字,而又没有显式地映射视图,一个进程不能访问另一个进程的内存映射文件。

4,实际中RAM一般没有GB级别,Windows是使用虚拟镜像技术的(通过内存与磁盘的页置换完成的)。

5,程序中如果需要动态内存,可使用Win32函数VirtualAlloc和VirtualFree函数,也可以直接使用Windows 堆函数(如:HeapAlloc 和 HeapFree)和CRT函数(C运行库堆函数,如malloc,new,free,delete)来完成任务。

6,堆是特定进程的内存池。当程序需要内存块的时候,调用堆内存分配函数,并在使用完时调用相关的堆内存释放函数释放内存。
Windows 堆函数(如:HeapAlloc 和 HeapFree)和CRT函数(C运行库堆函数,如malloc,new,free,delete).
C++代码中,new,delete函数直接映射到malloc,free函数。
说明:
new,delete函数与malloc,free函数比较优点:new,delete函数进行类型检查,自动计算要分配类型的大小,而且属于C++语言的一部分。malloc,free函数是作为标准库函数提供给C的,它们并不是C语言的一部分。

7, 内存映射文件:
处理如在程序中读如DIB(设备无关位图文件)的问题时候:文件小一般是分配一个大小合适的缓冲区,打开文件,然后把整个文件读入缓冲区;如果文件大则可使内存映射文件来处理。
内存映射文件是:直接映射一个地址范围到相应的文件(注:个人理解 文件仍然存放在存放在磁盘上),当进程访问该范围内存页时候,OS分配RAM并从磁盘中读入该页数据。
说明:
1)默认情况下,当映射文件时候,虽然可能只映射文件的一部分,但整个文件仍然被占用。
2)MFC里不支持内存映射文件。CSshareFile类只支持HGLOBAL句柄进行剪切板内存传输,不大实用。

8,资源包含在EXE和DLL里,因此会占用虚拟地址空间,而且这些空间在进程的生存期内不会被改变。这就使我们很容易直接读取一个资源(如用LoadResource函数加载位图资源)
说明:
LoadResource : loads the specified resource into global memory.
HGLOBAL LoadResource(
  HMODULE hModule, // resource-module handle
  HRSRC hResInfo   // resource handle
);
LoadResource返回一个HGLOBAL值,但可以安全把它当成指针来使用(强制转换)。

9,堆使用的越多,程序的运行效率就越底下。WIN32程序的堆可以很大(要多大就有多大,没有64KB限制,WIN16有16K的限制)。
                                                                                                                              

//
说明:由于缺乏这方面的编程经验,书中翻译的这部分内容有比较拗口难懂,笔记里删漏好多的内容,建议看看原著。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值