2014-09-19 73 views
2

在低內存的Linux系統上,我有一個由單個可執行文件和多個共享庫組成的項目。這些庫不與其他可執行文件共享,並且任何時候只有一個可執行文件實例正在運行。有人告訴我,這種設置允許共享庫在未處於活動狀態時從內存中卸載。它是否正確?在Linux上使用共享庫來減少內存負載

在我看來,僅僅將整個項目構建爲一個靜態二進制文件(當然不包括系統共享庫)會更有意義,因爲每個函數只有一個副本在內存中處於活動狀態。

這兩種方法有什麼不同嗎?

+0

如果你真的絕望了,你可以使用'dlopen'和'dlclose'手動加載和卸載庫,如果你的程序不需要一直使用所有庫。 – markgz 2014-09-20 02:03:57

回答

5

有人告訴我,該設置允許共享庫在未處於活動狀態時從內存中卸載。它是否正確?

從某種意義上說,是的。如果內存壓力變高,內核內存管理器會處理這個問題。只讀部分(如代碼)可以簡單地從內存中刪除,並在需要時從原始文件重新加載。其他部分可以換出到交換文件。完全未使用的代碼和數據甚至不會被加載到內存中。加載或「卸載」的粒度是1個內存頁面,通常爲4096個字節。 (即它不是每個函數/文件或任何類似的東西)

然而,它對於可執行文件與共享庫完全相同 - 如果只有一個可執行文件,則不會通過使用共享庫獲得任何相關信息使用這些共享庫。

如果有幾個不同的可執行文件使用相同的共享庫,它們可以共享共享庫的只讀部分的內存,所以在這種情況下可以節省內存。這是一個很小的代價,你的共享庫應該被編譯爲PIC代碼,這通常會導致編譯後的代碼稍微大一點,並且執行速度要慢幾個百分點。

+1

由於只有一個可執行文件使用庫,靜態鏈接可能節省空間*和*時間... – Deduplicator 2014-09-20 00:05:50

+2

靜態鏈接,特別是如果使用'-fdata-sections -ffunction-sections -Wl,-gc-sections'或更好但LTO幾乎肯定會節省大量空間。靜態鏈接總是可以節省時間。 – 2014-09-20 01:11:39