共享库和静态库的区别:
静态库:
程序在编译的时候,将程序调用的静态库中的函数全部编译到生成的二进制文件中(仅限被调用的函数,而不是整个静态库中的所有函数),编译生成的二进制文件,体积比较大,执行时,比较占用内存(多个类似程序同时运行,需要加载多分静态库的函数,每个进程拥有自己的虚拟地址空间),但是所需要的函数都已经完全准备好。
动态库:
程序在编译的时候,只是加载了一小段能够在运行时绑定被调用函数的存根,根据系统的实际策略,可能在程序启动的时候,加载动态库,或者在库函数被第一次调用的时候,加载动态库。加载是页面为单位进行的,而不是像静态库那样,一次装入所有需要的页(不过系统会有自己的分页机制,实际执行的时候,静态编译的程序也不是一次性全部装入内存的,根据内存当时的使用情况和操作系统的内存管理策略,有不同的装入机制)。在此之前,如果有其他程序已经加载了这个动态库相关的页面,则不需要再次装入,共享即可(可以节省部分内存,动态库的真正作用)。
分析:
如果是同一份程序代码,分别使用静态库和动态库编译出不同的二进制程序,并且同时启动多次,可以肯定的是,使用动态库的程序节省内存。
如果是不同的程序,根据实际情况,动态库不一定比静态库节省内存,但是肯定不会比使用静态库的程序,占用更多的内存。
而如果计算机的内存特别小,小到无法容纳动态库中需要共享的页面,使用静态库或者使用动态库,似乎没有什么区别,因为动态库也无法实现共享(理论上如此,实际内存不可能这么小)。
备注:
共享库,实际上是内存映射文件机制的一个特例,内存映射文件机制的思想是,系统可以通过一个系统调用,将一个大的文件映射到进程的虚拟地址空间中,但是并不是实际的读取(没有装入内存),而是在需要访问该文件的时候,再以页为单位装入内存,进行读写。当有其他的进程需要访问同一个文件的时候,即可以共享(类似动态库的共享),并且可以立刻看到上一个进程写操作的结果,最后所有程序退出或者显示的解除该文件的映射时,系统将内存中改动的内容,写回到磁盘。
内存映射文件机制,是可以节省内存的。如果用i/o的方式,访问文件的话,每次都要将整个文件读入内存进行处理。
问题:
1. 内存映射文件,是否有同步的问题呢,如果一个进程还没有写完,另外一个进程又开始写,并且写入内容比较多的时候,内存映射发生变化的话,系统又是怎么处理的呢?i/o方式是否也可以共享内存呢?
共享库,是只读的,不存在这个问题。