静态链接 :不同的程序开发者和部门能够相对独立地开发和测试自己的程序模块,大大促进了程序开发效率。
优点:
1、代码装载速度快,执行速度略比动态链接库快;
2、只需保证在开发者的计算机中有正确的.LIB文件,在以二进制形式发布程序时不需考虑在用户的计算机上.LIB文件是否存在及版本问题。
缺点:
1、浪费内存和磁盘空间、模块更新困难;
2、会给对程序的更新、部署和发布带来很多麻烦。
例如:在多进程操作系统情况下,假如每个程序内部除了都保留着printf()函数、scanf()函数、strlen()等公用库函数,还有数量相当可观的其他库函数及它们所需要的辅助数据结构。
假如说程序program1和program2都公用lib.o这个模块,同时运行Program1和program2时,lib.o在磁盘中和内存中都有两个副本。
动态链接基本思想:把链接过程推迟到运行时再进行。
优点:
1、解决了共享目标文件多个副本浪费磁盘和内存空间的问题;
2、使开发过程中各个模块 更加独立,耦合度变小,便于不同的开发者和开发组织之间独立进行开发和测试。
3、在内存中共享一个模块:节省内存,还可减少物理页面的换入换出,也可增加CPU缓存的命中率,因为不同进程间的数据和指令访问都集中在了同一个共享模块上。
4、加强程序的兼容性,一个程序在不同平台运行时可以动态地链接到由操作系统提供的动态链接库。
例如:program1编译后生成program1.o目标文件,其运行后,当再运行program2,只需加载program2.o,不需重新加载lib.o,因为内存中已经存在来一份lib.o的副本。
缺点:如果使用载入时动态链接,程序启动时发现DLL不存在,系统将终止程序并给出错误信息。而使用运行时动态链接,系统不会终止,但由于DLL中的导出函数不可用,程序会加载失败;速度比静态链接慢。当某个模块更新后,如果新模块与旧的模块不兼容,那么那些需要该模块才能运行的软件,则会出现错误。
在Linux系统中,ELF动态链接文件被称为动态共享对象(DSO,Dynamic Shared Objects),以".so"为扩展名;在Windows系统中,动态连接文件被称为动态链接库(Dynamical Linking Library),以“dll”为扩展名的文件i,而静态链接则是以“.lib"为扩展名的文件。
据估算,动态链接与静态链接相比,性能损失大约在5%以下,但这点性能损失用来换取程序在空间上的节省和程序构建和升级时的灵活性,是相当值得的。
动态链接比静态链接慢的主要原因:动态链接下对于全局和静态的数据访问都要进行复杂的GOT定位,然后间接寻址;对于模块间的调用也要先定位GOT(全局偏移表),然后再进行间接跳转。
另一个减慢运行速度的主要原因是动态链接的链接工作是在运行时完成的。动态链接器会寻找并装载所需要的共享对象,然后进行符号查找地址重定位工作。
解决方法是:
延迟绑定(Lazy Binding) :当函数第一次被用到时才进行绑定(符号查找,重定位等),不用到则不进行绑定。 这样可大大加快程序的启动速度。