一、静态链接的缺点
1、浪费内存和磁盘空间
假设模块A和B都依赖于C,采用静态链接的方式,C库被链接到A和B,这样无论是存储在磁盘还是在内存运行时,模块C都有2个副本。
2、程序维护麻烦
假设程序依赖很多库,其中任意一个修改了bug或进行了更新,都需要重新链接,重新发布。
二、动态链接(Dynamic Linking)
把链接过程推迟到运行时再进行。
假设模块A和B都依赖于C,采用动态链接的方式,在运行时,模块C在内存中只有一份,由A和B共享,在磁盘中也只有一份独立的C共享库即可。
采用动态链接,解决了上面提到的静态链接的两个缺点。
动态链接的过程大致是先递归的将依赖库加载到内存,然后进行符号解析和地址重定位,最后执行入口点程序。
三、动态链接不代表十全十美
1、共享库的版本控制问题
动态链接的基本思想是将程序拆分为各个相对独立的模块。一个常见的问题是,当程序所依赖的某个模块更新后,由于新旧模块的接口不兼容,导致原有的一些程序无法运行。
2、性能损耗
采用动态链接,程序每次运行时都要重新进行链接,这样会导致一些性能损耗。使用延迟绑定(Lazy Binding)可以尽量减小这种性能损耗,但貌似Android系统还不支持延迟绑定。
四、如何快速了解动态链接的整个过程
最快的学习方式是看代码,比如通读Android系统的Linker代码。整个Linker的代码量不是很大,但前提要对ELF格式有一定的理解。
学习资料: 《程序员的自我修养——链接、装载和库》