主記憶體:配置、連結與分段
共享程式庫(a shared library)
想像一間繁忙圖書館裡,一本用鏈條栓在桌上的參考字典,由每個走上前來的人查閱,而不是每位訪客都扛著自己那本沉重的副本。共享程式庫就是程式的那本公共字典:一束許多程式可以同時使用的常式(函式),只載入記憶體一次並共享,而不是複製進每個程式。
具體來說,共享程式庫是一個由編譯好、可重用的程式碼構成的檔案——Linux 與 macOS 上是 .so 檔、Windows 上是 .dll——程式對它做動態連結。在啟動時,載入器把共享程式庫映射進記憶體;於是多個執行中的程式可以同時使用它程式碼在記憶體中的同一份副本。這之所以行得通,是因為程式庫的程式碼是位置無關的(不論被映射到哪裡都正確執行),而唯讀的程式碼可以安全共享:作業系統安排讓所有程式看到同樣的程式庫程式碼實體頁,所以即使有一百個程式在用,程式碼在 RAM 中也只存在一份。
為什麼重要:共享程式庫藉由避免重複,省下大量記憶體與磁碟,並讓你修正或升級一個程式庫一次,每個程式都受惠。它們是動態連結實際的歸宿。問題在於那份依賴:程式需要正確的共享程式庫在執行時存在且相容,所以缺少程式庫與版本衝突的錯誤就是共享的代價。請注意,只有唯讀的程式碼是真正共享的;每個程式仍各自取得程式庫可寫資料的私有副本。
在 Linux 上,數十個程式對 libc.so(C 標準程式庫)做連結。在執行時,libc 程式碼的一份實體副本位於記憶體中,而那每一個程式的分頁表都指向它——一份副本,所有人共享。
程式碼在記憶體中的一份副本,由許多程式透過共享頁使用。
共享只適用於唯讀的程式碼;每個行程保有程式庫可寫(資料)部分的私有副本。而這份便利伴隨版本依賴的風險——正確的共享程式庫必須在執行時存在。
又稱
另見