c 記憶體管理

2021-10-11 01:51:52 字數 2057 閱讀 7062

記憶體管理是c++和其他oop(物件導向)語言的根本區別,熟知c++的記憶體管理至關重要

在c++中,記憶體分成5個區,他們分別是堆、棧、自由儲存區、全域性/靜態儲存區和常量儲存區。

主要的區別由以下幾點:

管理方式不同。棧系統管理,堆程式設計師控制,容器產生記憶體洩漏(memory leak)

空間大小不同。堆大,棧小。棧可以 設定

能否產生碎片不同。頻繁的new/delete勢必會造成記憶體空間的不連續,從而造成大量的碎片,使程式效率降低。棧是先進後出,記憶體永遠是連續的

生長方向不同。堆向上生長(記憶體位址增加的),棧向下生長(向著記憶體位址減小的方向增長)

分配方式不同。堆:動態分配,沒有靜態分配。棧:靜態分配,動態分配。靜態分配是編譯器完成的,比如區域性變數的分配。動態分配由alloca函式進行分配,但是棧的動態分配和堆是不同的,他的動態分配是由編譯器進行釋放,無需我們手工實現。

分配效率不同。棧是機器系統提供的資料結構,計算機會在底層對棧提供支援:分配專門的暫存器存放棧的位址,壓棧出棧都有專門的指令執行,這就決定了棧的效率比較高。堆則是c/c++函式庫提供的,它的機制是很複雜的,例如為了分配一塊記憶體,庫函式會按照一定的演算法(具體的演算法可以參考資料結構/作業系統)在堆記憶體中搜尋可用的足夠大小的空間,如果沒有足夠大小的空間(可能是由於記憶體碎片太多),就有可能呼叫系統功能去增加程式資料段的記憶體空間,這樣就有機會分到足夠大小的記憶體,然後進行返回。顯然,堆的效率比棧要低得多。

malloc與free是c++/c語言的標準庫函式,new/delete是c++的運算子。它們都可用於申請動態記憶體和釋放記憶體。

new/delete:物件在建立的同時要自動執行建構函式,物件在消亡之前要自動執行析構函式

以下示例展示了malloc和new對於建構函式的是否觸發

#include using namespace std;

class a

virtual ~a()

void print()

};int main()

cout << "--stack--" << endl;

cout << "--heap with new--" << endl;

cout << "--heap with malloc--" << endl;

return 0;

}

輸出

construct

hello world

destruct

--stack--

construct

hello world

destruct

--heap with new--

hello world

--heap with malloc--

tcmalloc就是乙個記憶體分配器,管理堆記憶體,主要影響malloc和free,用於降低頻繁分配、釋放記憶體造成的效能損耗,並且有效地控制記憶體碎片。glibc中的記憶體分配器是ptmalloc2,tcmalloc號稱要比它快

在實際的程式中,小物件分配的頻率要遠遠高於大物件,通過這種方式(小物件無鎖分配,大物件加鎖分配)可以提公升整體效能。

執行緒級別cache和程序級別cache實際上就是乙個多級的空閒塊列表(free list)。乙個free list以大小為k bytes倍數的空閒塊進行分配,包含n個鍊錶,每個鍊錶存放大小為nk bytes的空閒塊。在tcmalloc中,<=32kb的物件被稱作是小物件,>32kb的是大物件。在小物件中,<=1024bytes的物件以8n bytes分配,10251025則浪費127bytes。而大物件是以頁大小4kb進行對齊的,最多會浪費4kb - 1 bytes。

C 記憶體管理 C 記憶體分類

c 記憶體管理 記憶體分類 moakap 在編寫程式過程中,程式設計師必須清楚程式記憶體的分配機制,合理進行記憶體管理,這樣才能得到高效的程式。同時,如果對c 記憶體分配基本概念不理解,使用不當,一方面浪費了寶貴的記憶體資源,降低了程式執行效率,另一方面還會造成程式中意想不到的錯誤。在 c 程式中,...

C 記憶體管理

在嵌入式系統中使用c 的乙個常見問題是記憶體分配,即對new 和 delete 操作符的失控。具有諷刺意味的是,問題的根源卻是c 對記憶體的管理非常的容易而且安全。具體地說,當乙個物件被消除時,它的析構函式能夠安全的釋放所分配的記憶體。這當然是個好事情,但是這種使用的簡單性使得程式設計師們過度使用n...

c 記憶體管理

這裡對我暫時所了解的記憶體機制做個記錄,以後再補。首先是記憶體分配 記憶體主要分為3個部分 一是從靜態儲存區域分配。編譯時分配好,主要存放全域性變數,static變數,程式結束釋放。二是從堆疊區域分配。函式內區域性變數存放的地方。隨變數生命週期自動釋放。效率較高,但大小有限。三是從記憶體池分配,即從...