1 静态库
在共享库出现之前,公用功能是以静态库的形式存在的,它把通用功能模块的多个目标文件打包在一起,用到它的程序只需要在链接时指定这个库文件,链接器就会从这个库中抽取出用到的功能代码拷贝到目标程序中,而不需要每次都对这些通用功能代码重新编译。
静态库体现出了很好的模块化思想,但是随着计算机产业规模的发展,静态库逐渐暴露出了自身两个比较严重的问题。
一是磁盘和内存空间占用大。静态库虽然加快了编译速度,提高了不同部门间的协作效率,但是在每个与静态库链接的程序中,都会保存一份引用到的通用功能代码的拷贝,而且在运行时,每一份拷贝都要占用相应的物理内存。
二是库的版本升级非常麻烦。一旦公用库有修改,每个引用到它的程序都需要与新版本的库重新链接。在库与应用是由不同的公司或组织维护的场景下,升级工作将变得异常复杂。通用库中如果有 Bug 修复,使用该库的所有应用都需要分别升级。
2 共享库
为了解决这两个问题,共享库技术应运而生。
首先,使用共享库的应用在编译链接时,并不把库中的功能代码拷贝到目标文件中,而只在目标文件中记录一条引用信息,标记引用到的库函数,直到程序运行时才由动态链接器去定位功能代码的位置,因此生成的可执行程序的体积得以明显地减小。
其次,每个共享库在物理内存中只有一份副本,多个应用会在各自的虚拟地址空间内映射这同一份可执行文件,因此可以节省可观的内存空间。
共享库的这种工作方式大大方便了库的升级,当共享库发布新版本时,用户只需要升级这个共享库,所有使用这个库的应用就可以自动获得新库中的特性或 Bug 修复,而不需要单独升级每个应用。