在网上搜索后,我似乎找不到答案。
当我第一次使用 dlopen 时,它似乎比此后的任何时间都花费更长的时间,包括如果我从程序的多个实例运行它。
dlopen 是否将 so 加载到内存中一次并让操作系统保存它,以便任何后续调用(甚至来自程序的另一个实例)都指向内存中的同一位置?
那么基本上运行一个库的程序的 3 个实例是否意味着同一个 .so 的 3 个实例被加载到内存中,或者内存中只有一个实例?
Thanks
dlopen 是否将 so 加载到内存中一次并让操作系统保存它,以便任何后续调用(甚至来自程序的另一个实例)都指向内存中的同一位置?
多次致电dlopen
从单个进程内保证不会多次加载库。来自man page http://man7.org/linux/man-pages/man3/dlopen.3.html:
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
and .rodata
部分(通常驻留在单个 RO 段中)被映射为只读,.data
and .bss
部分被映射为读写。
随后的dlopen
从另一个进程执行相同的操作mmap
s。然而,操作系统不必从磁盘加载任何只读数据——它只是增加已经加载的第一个页面的引用计数dlopen
称呼。这就是“共享库”中的共享。
那么基本上运行一个库的程序的 3 个实例是否意味着同一个 .so 的 3 个实例被加载到内存中,或者内存中只有一个实例?
取决于你所说的“实例”。
每个进程都有自己的一组(动态分配的)运行时加载器结构来描述该库,并且每组都将包含共享库的一个“实例”(可以在不同进程中的不同地址加载)。每个进程还将有自己的可写数据实例(使用写时复制语义)。但是只读映射都将占用相同的物理内存(尽管它们可以出现在每个进程中的不同地址)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)