在Linux中共享可执行的内存页面?

为了保存空间,是否可以在Linux上共享可执行页面? 我知道有共享的内存API可以用来在不同的进程之间共享内存,但我不认为这是用来做这件事的。

基本上,我想有一个共享内存区域,可以加载一些常用的共享库。 我想让dynamic连接器链接到预加载的(只读)图像,而不是必须将所有的共享库图像加载到每一个进程(这看起来像是浪费)。

这是可能的Linux内核? Darwin内核使用Mach VM的特性(称为commpages)dyld共享高速caching存储在那里)来实现这一function。 交易是可以访问和分享每个进程之间的。

为了澄清,我知道共享对象(库)是什么。 目前,dynamic连接器在Linux上的作用是将所有必需的库加载到程序的地址空间中,这意味着每个与libc链接的应用程序在其地址空间中都会有一个libc映像。 在Darwin上,可以通过在一组共享内存页面具有 libc的可执行文件(和其他只读文件)来消除这个问题。 共享图像的可写部分仍然是分开的。

编辑:我知道ELF格式不支持分离共享库的数据和文本段。 我没有使用ELF, 我使用了不同的二进制格式(使用我自己的binfmt内核模块和我自己的dynamic链接器) 。 如果Linux内核支持类似commpage的function,我很感兴趣。

编辑2:我能想到这样做的唯一方法是在内核中分配一大块内存,并将其映射到每个执行的二进制文件中。 第一次执行任何二进制文件时,dynamic连接器可以解除保护,填充所需的数据并保护它。 然后不知何故,内核将不得不确保内存段没有被其他任何东西修改,因为它会打开一个巨大的安全漏洞。 另一个

Solutions Collecting From Web of "在Linux中共享可执行的内存页面?"

正如geekosaur所说,Linux已经这样做了。

在应用程序启动时,动态链接器(ld.so) mmap()是共享库。 它对每个库执行mmap()几个调用:

  • 可执行部分的mmap(PROT_READ|PROT_EXEC) (即.text)
  • 数据(即.data和.bss)的mmap(PROT_READ|PROT_WRITE)

(你可以使用strace来检查这个。)

内核作为一个巧妙的代码,意识到由offset和inode(通过fd已知)标识的可执行部分已经被映射。 因为它是只读的,所以为它分配更多的内存毫无意义。

这也意味着,如果你有任何其他文件,你mmap()只读从多个应用程序的内存也将被消耗一次。

Linux已经这样做了; 实际上,这就是共享对象的作用。