我很清楚Window堆分配和堆棧堆等。雖然是Linux的新手,但我沒有太多的清晰度,它是如何工作的?共享庫和可執行文件與Linux上的靜態C運行時間鏈接。他們每個人都有像Windows一樣的單獨堆嗎?
在Windows上:
- 在一個進程的開始,操作系統創建一個名爲進程堆一個默認堆。如果沒有使用其他堆,則使用進程堆分配塊。
- 語言運行時間也可以在一個過程中創建單獨的堆。 (例如,C運行時創建自己的堆)
- 除了這些專用堆,應用程序或許多加載的動態鏈接庫(DLL)之一可能會創建並使用單獨的堆,稱爲私有堆
- 這些堆位於所有虛擬內存系統中操作系統的虛擬內存管理器之上。 a)C/C++運行時(CRT)分配器:提供malloc()和free()以及新的和刪除操作符。 b)CRT作爲其初始化的一部分,爲其所有分配創建了一個額外的堆(該CRT堆的句柄在CRT庫內部存儲在名爲_crtheap的全局變量中)。 c)CRT創建自己的私有堆,它位於Windows堆的頂部。 d)Windows堆是圍繞Windows運行時分配器(NTDLL)的薄層。 e)Windows運行時分配器與虛擬內存分配器進行交互,虛擬內存分配器保留並提交操作系統使用的頁面。
我們的DLL和exe鏈接到多線程靜態CRT庫。我們創建的每個DLL和exe都有一個自己的堆,即_crtheap。分配和解除分配必須從各個堆發生。動態分配的DLL不能從可執行文件中取消分配,反之亦然。
編譯我們的代碼在DLL和EXE的使用/ MD或/ MDD使用多線程特定和DLL特定版本的運行時庫,將DLL和EXE鏈接到相同的C運行時庫,因此一個_crtheap。分配總是與單個模塊內的解除分配配對。
這與Liunx上的行爲相同嗎? 那裏有什麼堆?怎麼樣CRT堆?
非常感謝您的洞察力。當一個靜態鏈接到libc的共享庫被一個可執行文件加載時會發生什麼,該可執行文件也與libc靜態鏈接。那麼會有兩堆嗎?如果從內存中分配內存並從其他內存中釋放內存,會是一個問題嗎? –
我不知道......靜態鏈接並不總是得到很好的支持,而且我認爲如果你已經走到了盡頭,最終會得到與運行代碼鏈接的同一個庫的2個副本,那麼你已經犯了嚴重的戰略錯誤。 –