共享对象开销

Pau*_*aet 5 c linux embedded shared-libraries

我们有一个非常模块化的应用程序,有很多共享对象(.so).有些人认为,在内存/闪存有限的低端平台上,最好将所有内容静态链接到一个大的可执行文件中,因为共享对象有开销.

你对这个有什么看法 ?

最好的祝福,

保罗

R..*_*R.. 7

共享库的成本大致(每个库):

  • 至少4k的私人脏内存.
  • 至少12k的虚拟地址空间.
  • 多个文件系统在加载时访问系统调用mmapmprotect系统调用,以及至少一个页面错误.
  • 是时候解决库代码中的符号引用了.

加上与位置无关的代码成本:

  • 丢失一个通用寄存器(这在x86(32位)上可能很大,但在其他拱门上大多无关紧要).
  • 访问全局/静态变量(和常量)的额外级别的间接访问.

如果您有一个长期运行的大型应用程序,那么成本可能对您来说无关紧要,除非您使用的是小型嵌入式系统.另一方面,如果您正在编写可以多次调用的短期任务(如语言解释器),这些成本可能会很高.将所有标准模块放在他们自己的.so文件中而不是默认情况下静态链接它们是Perl,Python等开始这么慢的原因的一个重要原因.

就个人而言,我会采用使用动态加载模块作为可扩展性工具的策略,而不是作为开发模型.


Kev*_*eer 5

除非内存非常紧张,否则这些文件的一个副本的大小不是主要决定因素.鉴于这是一个嵌入式系统,您可能很清楚哪些应用程序将使用您的库以及何时使用.如果您的应用程序打开并关闭它所引用的多个库,并且您永远不会同时打开所有库,那么共享库将大大节省RAM.

您需要考虑的另一个因素是性能损失.打开共享库需要很少的时间(通常是微不足道的); 如果您的处理器速度非常慢或实时性要求很高,则静态库不会导致共享库的负载损失.查找是否重要的​​配置文件.

总而言之,在某些特殊情况下,共享库可能明显优于静态库.在大多数情况下,它们几乎没有伤害.在简单的情况下,您无法从共享库中获益.


当然,如果您有多个使用相同库的应用程序(或您的应用程序版本),共享库将大大节省Flash.如果使用静态库,则会将一个副本(与共享库[1]大小相同)编译到每个副本中.当您在PC工作站上时,这非常有用.但你知道的.您正在使用仅由一个应用程序使用的库.


[1]各个库文件的内存差异很小.共享库添加索引和符号表,以便dlopen(3)可以加载库.这是否重要取决于您的使用案例; 为每个编译然后比较大小以确定Flash中哪个更小.你必须运行和配置文件来确定哪个消耗更多的RAM; 它们应该是相似的,除了初始加载共享库.