c++記憶體管理學習:
記憶體池。
1.為什麼要記憶體池:
每malloc一次不僅需要呼叫brk/mmap系統呼叫函式,還會產生上下兩個用來標識一塊被使用的記憶體的cookie。如果申請的記憶體只有8位元組膨脹率將會達到百分之100。若分配100萬次記憶體就會有800萬位元組的cookie。記憶體池的作用就是減少malloc的開銷、減少浪費的cookie(宗旨就是快、省)。
2.記憶體池原理:
簡介記憶體池:顧名思義就是使用者自己管理一大塊記憶體池,每次使用前先看池中是否有空餘,有的話直接拿出,沒有的話才使用operator new()向核心要一塊記憶體。
首先需要明白c++ new這個不可過載的運算子的性質:
一.new 中做了三件事:
1.operator new :分配記憶體(可過載,若使用標準分配器其實就是呼叫malloc並做了返回值判斷)。
2.static_cast:將operator new 返回的void*轉為左值物件型別。
3.constructor:呼叫建構函式。
4.(提一下)placemenet new 由於使用者無法直接呼叫建構函式(編譯器會報錯),c++中提供了placement new 這種方式來構造一塊分配好的記憶體。
想要實現記憶體池顯然只能通過過載operator new
在operator new 中每次要一大塊記憶體(gnu中是不超過所需物件的20倍,且每新開闢一塊記憶體時向核心索要20x2倍 該物件的大小 + 已分配/16)
二.如何管理一塊記憶體池:
使用嵌入式指標(union)來實現記憶體池的管理,union這個關鍵字指明它的記憶體大小為union中最大的物件型別的大小。
記憶體池的使用分為2步:第一步分配一大塊記憶體,第二步:從記憶體池中取出一塊記憶體並調建構函式構造這塊記憶體,此時該記憶體方可被使用者使用。也就是說在取出前我們可以借用這些未被使用的記憶體來實現對記憶體池的管理。
一般實現方式:利用union使用每個該物件記憶體的前4個位元組(乙個指標),利用這個指標將記憶體池串聯起來(單向鍊錶)。為何要這樣做:若有記憶體被釋放,只需將此記憶體插入鍊錶尾即可。
三.我實現的簡易記憶體池:
四.記憶體池是如何處理記憶體碎片的:
gnu中_pool_alloc的設計:
簡介_pool_alloc設計:這個構造器只接受8~128位元組大小的物件構造(第乙個籃子8位元組、第二個籃子負責16位元組。。。以此類推。若不足則補足,如95此時對齊為96,8的整數倍)。
如圖所示當出現記憶體碎片時:
記憶體池中只剩24位元組了下次我們要申請的物件為32位元組,此時記憶體池乙個該物件的記憶體都無法提供,此時產生記憶體碎片。
解決方法:將此24位元組插入第三個籃子中(負責24位元組的籃子),這樣記憶體碎片將不復存在(由於最小單位為8位元組,所以記憶體碎片的大小必為8的倍數)。
五.總結
左右值引用、寫入時拷貝…這些都是c++為了追求效率而引入的特性。這些東西都和記憶體掛鉤,像c/c++這種自由(隨意操控記憶體)的語言記憶體管理是不可繞過的坎,雖然很多編譯器都自帶了記憶體管理的類(malloc也是)但是深入原始碼去看看這些優秀的記憶體管理庫也是必要的,只有了解這些好東西的設計才能做到活現活用、心中自有丘壑。注:此篇為c++記憶體管理的入門篇。
管理 專案管理入門
karl e.wiegers 著,mirnshi 譯 非程式設計師雜誌第3期 當你預期的那一天,也許是害怕的那一天,終於來到了 從工程師的隊伍裡你被提拔到了軟體專案領導或者團隊領導的位置。這也許就是你選擇的職業道路,或許你不太情願,將就嘗試一下。無論在哪種情況下,你都可能缺少工程學科 人員管理以及領...
專案管理入門
當你預期的那一天,也許是害怕的那一天,終於來到了 從工程師的隊伍裡你被提拔到了軟體專案領導或者團隊領導的位置。這也許就是你選擇的職業道路,或許你不太情願,將就嘗試一下。無論在哪種情況下,你都可能缺少工程學科 人員管理以及領導能力的相關教育。這需要更多的領導能力和管理 它們不是一回事 而不能象dilb...
專案管理入門
專案管理入門 karl e.wiegers 著,mirnshi 譯 非程式設計師雜誌 第3期 當你預期的那一天,也許是害怕的那一天,終於來到了 從工程師的隊伍裡你被提拔到了軟體專案領導或者團隊領導的位置。這也許就是你選擇的職業道路,或許你不太情願,將就嘗試一下。無論在哪種情況下,你都可能缺少工程學科...