Dlopen是否会创建多个库实例? [英] Does dlopen create multiple library instances?

查看:178
本文介绍了Dlopen是否会创建多个库实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在网上搜索后,似乎找不到答案。

当我第一次使用dlOpen时,它似乎比之后的任何时间都要长,包括如果我从一个程序的多个实例运行它。

dlopen是否将SO加载到内存中一次,并让操作系统保存它,以便任何后续调用(即使是来自程序的另一个实例)都指向内存中的同一位置?

那么基本上,运行库的程序的3个实例是否意味着相同.so的3个实例被加载到内存中,或者内存中只有一个实例?

谢谢

推荐答案

dlopen是否将SO加载到内存中一次,并让操作系统保存它,以便任何后续调用(即使是来自程序的另一个实例)都指向内存中的同一位置?

从单个进程内对dlopen的多个调用保证不会多次加载库。来自man page

   If the same shared object is loaded again with dlopen(), the same
   object handle is returned.  The dynamic linker maintains reference
   counts for object handles, so a dynamically loaded shared object is
   not deallocated until dlclose() has been called on it as many times
   as dlopen() has succeeded on it.

第一次调用dlopen时,库被mmap放入调用进程。通常至少有两个单独的mmap调用:.text.rodata部分(通常位于单个RO段中)映射为只读,.data.bss部分映射为读写。

来自另一个进程的后续dlopen执行相同的mmap。但是,操作系统不必从磁盘加载任何只读数据-它只增加已为第一次dlopen调用加载的页面上的引用计数。这就是"共享库"中的共享。

那么基本上,运行库的程序的3个实例是否意味着相同.so的3个实例被加载到内存中,或者内存中只有一个实例?

取决于您所说的"实例"。

每个进程都有自己的一组(动态分配的)运行时加载器结构来描述这个库,每组都包含一个共享库的"实例"(可以在不同的进程中加载到不同的地址)。每个进程还将拥有自己的可写数据实例(使用写入时复制语义)。但只读映射将全部占用相同的物理内存(尽管它们可能出现在每个进程中的不同地址)。

这篇关于Dlopen是否会创建多个库实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆