to Hao.Yu:“如果有地址冲突发生,比如加载DLL的时候发现该段内存已经被其他DLL占用,那么系统<br>就必须对此DLL进行重定位,这样代码段也不只一份了。”没错,但对于每个不同的DLL,内存<br>中只有一份Copy。<br>当一个应用程序使用了一个DLL,Win32系统会确保内存中只有一个该DLL的拷贝,这是通过内存映射文<br>件来实现的。每个进程都被分配有自己的32位线性地址空间。当一个DLL被多个进程调用时,每个进程<br>都会获得该DLL的一份映像。DLL被调入进程的地址空间时设置了基地址,如果DLL的基地址与已经分配<br>的DLL地址重叠的话,Win32重新分配基地址。这样,每一个重新分配的DLL实例都有自己的物理上的内<br>存空间和交换文件空间。这是很关键的,通过使用$IMAGEBASE指示符,给每个DLL都设置一个基地址,<br>这样不会引起冲突或不会出现地址重叠。<br>如果有多个应用程序都调用同一个DLL,系统会设置一个唯一的基地址,这样无论是在进程的低端地址或<br>者是在高端地址,都不会引起冲突。但进程间也不能共享DLL的数据。<br>在调用时,DLL不需要重新分配或安装,因为它保存在本地磁盘上,DLL的内存页面被直接映射到磁盘上的<br>DLL文件。DLL代码不需占用系统页面文件(也叫交换文件)的空间。这就是为什么系统提交页的总数和大小<br>可能比系统交换文件加内存要大。<br>可以看“Image Base Address”的帮助。