栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

共享库是否使用与应用程序相同的堆?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

共享库是否使用与应用程序相同的堆?

我的问题是这些库中的代码是否将在与主应用程序相同的堆中分配内存,还是使用自己的堆?

如果库使用与

malloc/free
应用程序相同的库(例如from
glibc
),则可以,程序和所有库都将使用单个堆。

如果库

mmap
直接使用,它可以分配的内存不是程序本身使用的内存。

因此,例如,.so文件中的某些函数调用malloc,它将使用与应用程序相同的堆管理器,还是使用另一个应用程序?

如果来自.so的函数调用malloc,则此malloc与从程序调用的malloc相同。您可以在Linux / glibc(> 2.1)中看到符号绑定日志

 LD_DEBUG=bindings ./your_program

是的,堆管理器的多个实例(具有默认配置)在不相互了解的情况下无法共存(问题在于使brk分配的堆大小在实例之间保持同步)。但是,当多个实例可以共存时,可能存在一种配置。

大多数经典的malloc实现(ptmalloc
*,dlmalloc等)可以使用两种从系统获取内存的方法:

brk
mmap
。Brk是经典堆,它是线性的,可以增长或收缩。Mmap允许在任何地方获得大量内存;您可以按任何顺序将此内存返回给系统(释放它)。

构建malloc时,可以禁用brk方法。然后,malloc将仅使用

mmap
s
来模拟线性堆,甚至将禁用经典线性堆,并且所有分配将由不连续的mmaped碎片进行。

因此,某些库可以具有自己的内存管理器,例如

malloc
,已
brk
禁用或使用非malloc内存管理器进行编译。该管理器应具有
malloc
和以外的函数名称
free
,例如
malloc1
free1
或不应将其显示/导出到动态链接器。

同样,那些共享内存中的全局数据又如何呢?它在哪里?对于应用程序,我知道它位于bss和数据段中,但是不知道这些共享对象文件在哪里。

您应该像ELF文件一样考虑程序和.so。每个ELF文件都有“程序头”(

readelf -lelf_file
)。如何将数据从ELF加载到内存的方式取决于程序标头的类型。如果类型为“
LOAD
”,则文件的相应部分将被私有
mmap
编辑(Sic!)到内存中。通常,有2个LOAD段。第一个用于带有R +
X(读+执行)标志的代码,第二个用于带有R +
W(读+写)标志的数据。两者
.bss
.data
(全局数据)区段被放置在型LOAD的段与写入启用旗标。

可执行库和共享库都具有LOAD段。某些段具有memory_size>
file_size。这意味着该段将在内存中扩展;它的第一部分将使用ELF文件中的数据填充,第二部分的大小(memory_size-
file_size)将使用零填充(对于

*bss
节),使用
mmap(/dev/zero)
memset(0)

当内核或动态链接器将ELF文件加载到内存中时,他们将不会考虑共享。例如,您想两次启动同一程序。第一个进程将使用mmap加载ELF文件的只读部分;第二个进程将执行相同的mmap(如果aslr是活动的-
第二个mmap将进入不同的虚拟地址)。页面缓存(VFS子系统)的任务是将数据的单个副本保存在物理内存中(使用COPY-
WRITE或COW)。mmap只会将每个进程中的虚拟地址映射到单个物理位置。如果有任何进程将更改内存页面;它将在写入时复制到唯一的专用物理内存。

加载代码在

glibc/elf/dl-load.c
_dl_map_object_from_fd
)中,用于ld.so和
linux-kernel/fs/binfmt_elf.c
内核的ELF加载器(
elf_map
load_elf_binary
)。搜索
PT_LOAD

因此,全局数据和bss数据始终在每个进程中私密地映射,并且它们受到COW的保护。

堆和堆栈在运行时使用brk +
mmap(堆)进行分配,并由OS内核自动在类似brk的进程中分配(用于主线程的堆栈)。其他线程的堆栈分配

mmap
在中
pthread_create



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/412408.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号