2017-02-23 77 views
0

我似乎無法找到一個答案後,在網上搜索出來。dlopen是否創建多個庫實例?

當我使用dlopen的第一次它似乎需要更長的時間比之後的任何時間,包括如果我從程序的多個實例運行。

dlopen的是否加載了所謂到內存中一次,並有OS保存它,這樣即使是從程序點的另一個實例在內存中的相同點以下的任何電話?

所以基本上不會運行庫的程序的3個實例意思是相同的。所以3個實例被加載到內存中,還是有隻有一個實例在內存中?

感謝

+3

它不叫白白共享庫。 –

+0

太棒了!我知道它是共享的,所以其他程序可以調用它。我有一個強大但未經證實的懷疑,即操作系統足夠聰明,只能將其記憶一次。感謝您及時的回覆。 – Questionable

+0

在我看來,這可能取決於操作系統的實現,但理論上dlopen應該在打開時mmap lib及其所有依賴項。然後在邏輯上聽起來是爲了重用原因在進程之間共享映射的內存。我想這種過程可能會以某種方式解釋你所觀察到的。但請記住,您的計時可能是由其他原因造成的,例如文件系統緩存或掃描。其他。 – dmi

回答

2

dlopen的是否加載了所謂到內存中一次並且操作系統將其保存,這樣即使是從程序點的另一個實例在內存中的相同點以下的任何電話?

保證多次調用dlopen從一個進程內多次不加載庫。從man page

If the same shared object is loaded again with dlopen(), the same 
    object handle is returned. The dynamic linker maintains reference 
    counts for object handles, so a dynamically loaded shared object is 
    not deallocated until dlclose() has been called on it as many times 
    as dlopen() has succeeded on it. 

何時dlopen第一次調用發生時,該庫是mmap版到調用進程。通常至少有兩個獨立的mmap調用:.text.rodata部分(通常駐留在單個RO段中)映射爲只讀,.data.bss部分映射爲可讀寫。

從另一個過程中的後續dlopen執行相同mmap秒。然而,操作系統不需要從磁盤加載任何只讀數據 - 它只是增加已經加載的第一個dlopen調用頁面上的引用計數。這就是共享「共享庫」。

因此,基本上運行庫的程序的3個實例是指3個相同的實例.so被加載到內存中,還是在內存中只有一個實例?

取決於你所說的「實例」。每個進程都有自己的一組(動態分配的)運行時加載器結構來描述這個庫,並且每個進程將包含共享庫的「實例」(可以在不同進程的不同地址加載)。每個進程也將擁有自己的可寫數據實例(使用寫時複製語義)。但只讀映射將全部佔用相同的物理內存(儘管它們可能出現在每個進程的不同地址中)。

+0

謝謝你的詳細解答。 – Questionable