2010-05-17 101 views
16

我有一个简单的小问题,谁知道谁会很容易回答,我搜索谷歌,但无法找到答案。.dll文件是为每个程序加载一次还是为所有程序加载一次?

有一台计算机上运行多程序同时,我的问题是:当一个程序加载DLL,它实际上加载DLL文件或者它在其中找到该DLL已经加载内存?例如,为每个使用winsock的程序加载ws2_32.dll(winsock 2),还是加载一次,并且所有使用它的程序都使用相同的内存地址来调用函数?

回答

18

它的满载一次,所有程序共享同一代码在内存中的副本。它有点复杂,但对于DLL的只读部分(即代码),操作系统加载程序使用称为“内存映射”的技术将DLL映射到进程的地址空间。尽管页面可能会将页面映射到其虚拟地址空间中的不同地址,但页面只会加载到所有进程的物理内存中一次。

但是,每个进程都有一个单独的数据部分(使全局变量不是共享的 - 除非你明确地请他们),他们显然也有一个单独的堆,以便动态分配的内存不共享。

+0

好的,谢谢,这是有道理的。我只需要知道从DLL指向函数的指针是否指向所有使用此函数的程序使用的地址。 – Nilbert 2010-05-17 02:22:20

+2

该问题的答案是“否”。函数指针是进程*虚拟地址空间*中的地址,并且在进程之间绝对不共享。 DLL可以在不同进程的不同地址加载,因此,即使使用相同的物理页面,函数指针的地址也会不同。 – 2010-05-17 02:25:34

+0

实际上,函数在两个不同的程序中具有相同的地址是极不可能的。在其之前的所有代码段贡献之后,DLL的代码将被映射到下一个可用地址空间。在Secure Linux中,使用加载地址随机化(以防止viri在攻击中使用硬编码地址)。你没有写病毒,是吗? :-) – wallyk 2010-05-17 02:30:40

5

这取决于你的意思是“装”什么。

DLL将共享使用的代码和数据来制备:最Windows环境兑现可共享(由码的同一存储器拷贝映射到每个进程的内存空间)以节省存储器。但是,从进程的角度来看,“加载”操作的一部分正在运行DLL的初始化:这是在每个进程中分别完成的,每个进程都有不同的数据区副本。

相关问题