前言
动态链接是一种高效且节省空间的程序间共享代码方式。若程序使用静态链接方式,则程序所有代码都将集成到同一个二进制文件中,其优点在于无依赖关系,可以在不同运行环境的OS下运行。但是缺点也十分明显,由于二进制文件中包含全部代码,所以所占空间较大;如果多次运行同一个程序,则OS可能会对某个库函数进行多次重复 的加载,占用了不必要的内存;若某个公用的库函数产生了更新,则需要重新编译所有使用了该库的程序,工作量较大。
静态链接的一个典型的例子就是Golang,其默认所有程序都是使用静态链接的方式,包含有所有使用到的Golang库函数,因此使用Golang编写的程序因为具有优秀的可移植性和开箱即用受到较多好评。但较为直观的也能看见上面所说的缺点:Linux x86_64下,一个Golang编写的HelloWorld二进制文件占用空间为1.7MB。
而为了解决静态链接存在的重复加载、重复编译等问题,引入了动态链接的方式。使用动态链接的程序不包含库函数的代码,库函数通过动态链接库(.so)的形式独立存在。当程序开始运行并产生外部函数调用时,动态链接器将承担加载动态链接库和重定位函数地址、变量地址的工作,在运行时确定外部函数地址和变量的值,也叫惰性加载。动态链接能够减少程序的启动时间(程序占用空间变小),且动态链接器也不会产生较多额外的性能开销,因此动态链接还是如今比较广泛应用的一种链接方式。