当前位置: 首页 > 面试题库 >

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

潘楚
2023-03-14
问题内容

假设我在Linux中有一个使用共享库(.so文件)的应用程序。我的问题是这些库中的代码是否将在与主应用程序相同的堆中分配内存,还是使用自己的堆?

因此,例如,.so文件中的某些函数调用malloc,它将使用与应用程序相同的堆管理器,还是使用另一个应用程序?同样,那些共享内存中的全局数据又如何呢?它在哪里?对于应用程序,我知道它位于bss和数据段中,但是不知道这些共享对象文件在哪里。


问题答案:

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

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

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

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

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

 LD_DEBUG=bindings ./your_program

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

大多数经典的malloc实现(ptmalloc
*,dlmalloc等)可以使用两种从系统获取内存的方法:brkmmap。Brk是经典堆,它是线性的,可以增长或收缩。Mmap允许在任何地方获得大量内存;您可以按任何顺序将此内存返回给系统(释放它)。

构建malloc时,可以禁用brk方法。然后,malloc将仅使用mmaps
来模拟线性堆,甚至将禁用经典线性堆,并且所有分配将由不连续的mmaped碎片进行。

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

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

您应该像ELF文件一样考虑程序和.so。每个ELF文件都有“程序头”(readelf -l elf_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_mapload_elf_binary)。搜索PT_LOAD

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

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



 类似资料:
  • 用例 用户A,游戏大师(GM)使用该应用程序上传一张地图图像和一些怪物的图像。该应用程序将图像上传到用户a的Google驱动器中创建的文件夹结构中,并通过链接将其标记为可读。 在用户A配置好东西后,应用程序会显示一个虚拟桌面,一个包含地图的3D空间,上面有一些怪物。描述桌面的JSON数据也存储在Google Drive中,应用程序通过链接将其标记为可读。 用户A与用户B(播放器)共享URL。该链接

  • 我有一个tomcat 8.0.32运行在windows上。 在tomcat\lib文件夹中,我有一个共享文件夹。jar文件。共享。jar是所有web应用程序都使用的全局共享库。该文件包含一个包含常量的java类: 我有2个Web应用程序正在使用这个CONSTANTVALUE。我删除shared.jar并将一个新shared.jar复制到tomcat\lib中,其中包含一个新的常量值: 我重新启动了

  • 我正在使用FB。允许用户使用此代码共享我的页面的ui: 当从 Android 移动应用程序中的嵌入式浏览器共享页面时,用户可以选择要用于打开共享对话框的应用程序。如果选择了脸书应用,则不会有回调响应。在普通的桌面浏览器中,一切都按预期工作。这种行为是预期的吗?

  • 我根据以下站点遵循了该过程:https://developer.vuforia.com/resources/dev-guide/step-3-compiling-running-vuforia-sample-app。 我试图通过cygwin构建ImageTargets共享库,但显示的消息是: 和

  • 我有三个azure功能和两个webapp,我希望所有应用都在同一个应用服务计划中,但azure manual和maven都不允许添加同一个应用服务计划。 在azure中,是否可以在同一应用程序服务计划中添加web和功能应用程序?