加载共享库与静态库的时间

时间:2010-01-08 04:13:48

标签: shared-libraries static-libraries

我对共享库与静态库加载时有疑问。

假设我有一个使用liba,libb,libc的可执行文件foo.exe。此外,在给定时间,机器上运行的可执行文件的实例超过10个。

现在,如果以上3个库是共享库: 第一个Insance被加载到RAM中:所花费的时间将是foo.exe的main()被加载内存所占用的时间(假设它可以忽略不计)+加载liba的时间+加载libb的时间+加载libc的时间 第二个实例启动:现在假设运行此可执行文件的第二个实例。自所有图书馆 已经加载到主内存中,所花费的时间仅用于将main()加载到可忽略不计的内存中。

现在,如果以上3个库是静态库: 第一个Insance加载到RAM中:所需的时间是要加载的foo.exe的main()所用的时间 内存(假设其可忽略不计)+加载liba的时间+加载libb的时间+加载libc的时间(Offcourse现在它作为一个整体的可执行文件的所有部分) 第二个实例启动:现在假设运行此可执行文件的第二个实例。所用的时间将是 再次将foo.exe的main()时间加载到内存中(假设其可忽略不计)+加载liba的时间+加载libb的时间+加载libc的时间。 (由于每个可执行文件都不能共享图书馆,因为这些是静态图书馆)

所以我的结论是,使用静态库,加载时间会更长。但我被告知共享库在加载过程中比静态库花费更多时间,因此会有延迟,因此共享库不是一个好选择。这怎么可能?

3 个答案:

答案 0 :(得分:9)

链接(解析引用)不是免费的。使用静态链接,在生成二进制文件时,一劳永逸地完成分辨率。使用动态链接时,必须在每次加载二进制文件时完成。更不用说编译为在共享库中运行的代码可能比编译为静态链接的代码效率低。确切的成本取决于体系结构和系统的动态链接实现。

对于32位x86指令集,使库动态化的成本相对较高:在ELF binary format中,必须牺牲其中一个已经稀缺的寄存器来使动态链接的代码可重定位。较旧的a.out格式将每个共享库放置在固定位置,但不能扩展。我认为,当动态库放置在地址空间中的预定位置时,Mac OS X有一个中间系统,但冲突是在单个计算机的规模上解决的(安装新计算机后的冗长的“优化系统性能”阶段)软件)。在某种程度上,这个系统(称为pre-binding)允许你吃蛋糕并吃它。 我不知道是否仍然需要预先绑定,因为Apple几乎切换到了amd64架构。

此外,在现代操作系统上,只有使用静态和动态链接的代码才会从磁盘加载(分页),但这与您的问题非常正交。

答案 1 :(得分:2)

静态库在编译时链接,共享库在运行时链接。因此,使用静态库的可执行文件在写入磁盘之前会分摊所有链接时间。

答案 2 :(得分:0)

非常感谢这种令人难以置信的快速反应。我们有2个architecural scenarious:

Q1。 Architecure-1:假设exe大小为3GB(静态库)。 95%是库,5%是main()。如此庞大的大小会加载这个exe需要更多时间(假设静态库)或者这个exe的链接需要更多时间(假设使用共享库,并且如果所有库已经在内存中只需要进行链接。)

Architecure-2:假设我的exe大小为1.5GB(95%lib + 5%main()),并且其中6个实例同时运行。一旦这6个实例启动,它们将运行数天,假设我们已准备好在初始加载+链接这6个实例期间采取额外的延迟。

Q2。现在,如果我使用共享对象而不是静态对象,我将在RAM上有大量可用空间,因为所有库都在6个实例之间共享?因为RAM中有更多的空间会减少页面交换,我的实时执行速度会不会加快?

Q3。如果我使用'map'文件来减少导出的符号数(这只能使用共享库),那么我的符号表大小是否会降低并且不会提高运行时性能吗?

由于 SUD