大家好,我是小風哥,今天簡單聊聊內存分配。mIL28資訊網——每日最新資訊28at.com
我們申請一塊內存時計算機內部發生了什么?看下這句代碼:mIL28資訊網——每日最新資訊28at.com
圖片mIL28資訊網——每日最新資訊28at.com
mIL28資訊網——每日最新資訊28at.com
這里有兩部分,一個是malloc,再一個是你寫的代碼。mIL28資訊網——每日最新資訊28at.com
圖片mIL28資訊網——每日最新資訊28at.com
mIL28資訊網——每日最新資訊28at.com
malloc實際上屬于標準庫,標準庫里有什么呢?mIL28資訊網——每日最新資訊28at.com
數學相關的函數,sin、cos、絕對值、數冪函數等;字符相關函數,判斷大小寫等;字符串操作函數、字符串拷貝、拼接比較等;當然還有內存管理函數,就是這里提到的malloc/free,當然還有很多其它函數,這就是標準庫。mIL28資訊網——每日最新資訊28at.com
圖片mIL28資訊網——每日最新資訊28at.com
再來看你寫的代碼,什么是你寫的代碼呢?以c語言為例,.c文件就是你寫的代碼,這包括你寫的hello world程序、充滿bug的練習程序,當然還有各種項目。mIL28資訊網——每日最新資訊28at.com
圖片mIL28資訊網——每日最新資訊28at.com
mIL28資訊網——每日最新資訊28at.com
這就是你寫的代碼。mIL28資訊網——每日最新資訊28at.com
這些代碼怎么變成最終的可執行程序呢?當然是借助編譯器。mIL28資訊網——每日最新資訊28at.com
編譯器會把你的代碼編譯成目標文件。mIL28資訊網——每日最新資訊28at.com
圖片mIL28資訊網——每日最新資訊28at.com
接著鏈接器出場,連接器會把目標文件和標準庫打包成可執行程序。mIL28資訊網——每日最新資訊28at.com
圖片mIL28資訊網——每日最新資訊28at.com
這就是代碼部分,接下來我們看內存分配。mIL28資訊網——每日最新資訊28at.com
到底什么是內存呢?mIL28資訊網——每日最新資訊28at.com
圖片mIL28資訊網——每日最新資訊28at.com
mIL28資訊網——每日最新資訊28at.com
內存實際上和儲物柜非常相似,儲物柜會劃分成了一個一個大小相同的隔間,每個隔間可以存儲東西,內存的道理也一樣,內存也被劃分成了一個一個大小相同的隔間,我們來仔細看一下。mIL28資訊網——每日最新資訊28at.com
圖片mIL28資訊網——每日最新資訊28at.com
mIL28資訊網——每日最新資訊28at.com
內存中的每個隔間存儲的是一個字節,8比特位一字節。mIL28資訊網——每日最新資訊28at.com
比如這里申請的一塊int大小的內存,一個int占據4個字節。mIL28資訊網——每日最新資訊28at.com
圖片mIL28資訊網——每日最新資訊28at.com
mIL28資訊網——每日最新資訊28at.com
和儲物柜一樣,內存中的每個隔間也有一個編號,這個編號叫做內存地址。mIL28資訊網——每日最新資訊28at.com
在我們的實例中,申請的這塊內存位于內存地址2這個位置,這意味著什么嗯?這意味著變量p等于數字2,或者說等于內存地址2,這里的p就是所謂的指針。mIL28資訊網——每日最新資訊28at.com
圖片mIL28資訊網——每日最新資訊28at.com
mIL28資訊網——每日最新資訊28at.com
接著我們看內存分配過程。mIL28資訊網——每日最新資訊28at.com
這段代碼當然屬于編譯后生成的可執行程序,可執行程序是在內存中運行的,當然我們需要為整個程序分配一塊內存。mIL28資訊網——每日最新資訊28at.com
圖片mIL28資訊網——每日最新資訊28at.com
程序的運行依賴棧區,這里存放著局部變量等信息;依賴堆區,這里存放著程序員自己管理的動態申請的內存,關于堆區和棧區之前的視頻也有講解;除此之外還依賴代碼區,這里保存的就是編譯后的之類;還有數據區,這里保存著全局變量等信息。mIL28資訊網——每日最新資訊28at.com
圖片mIL28資訊網——每日最新資訊28at.com
這些區域在內存中的布局是這樣的:mIL28資訊網——每日最新資訊28at.com
圖片mIL28資訊網——每日最新資訊28at.com
mIL28資訊網——每日最新資訊28at.com
再次強調下,編譯后的代碼位于代碼區,malloc動態申請的內存位于堆區,接下來我們只關注堆區。mIL28資訊網——每日最新資訊28at.com
在程序開始運行時堆區當然是空的,那么所謂的內存分配到底是什么呢?如果讓你實現內存分配器該怎么做到呢?很簡單,其實內存分配就是劃分地盤。mIL28資訊網——每日最新資訊28at.com
圖片mIL28資訊網——每日最新資訊28at.com
此時要分配第一塊大小為A的內存,那么你應該把A放在哪里呢?mIL28資訊網——每日最新資訊28at.com
圖片mIL28資訊網——每日最新資訊28at.com
因為此時堆區是空的,顯然你可以把開始這個位置劃分給A,作為A的地盤,找到A的地盤后malloc這個函數返回,內存分配過程結束,是不是很簡單。mIL28資訊網——每日最新資訊28at.com
圖片mIL28資訊網——每日最新資訊28at.com
接著程序員又開始申請大小為B的內存,道理和A一樣,把A之后的地盤給B即可。mIL28資訊網——每日最新資訊28at.com
圖片mIL28資訊網——每日最新資訊28at.com
程序員又開始申請大小為C的內存,同理。mIL28資訊網——每日最新資訊28at.com
圖片mIL28資訊網——每日最新資訊28at.com
mIL28資訊網——每日最新資訊28at.com
接著程序員說A占用的這塊內存使用完畢,調用free釋放,所謂釋放就是把A占據的地盤重新標記為空閑,這時堆區里還有兩塊空閑內存。mIL28資訊網——每日最新資訊28at.com
圖片mIL28資訊網——每日最新資訊28at.com
接著程序員開始申請大小為D,這時問題來了,你該從哪里給D劃分地盤呢?mIL28資訊網——每日最新資訊28at.com
圖片mIL28資訊網——每日最新資訊28at.com
mIL28資訊網——每日最新資訊28at.com
放到第一個空閑塊嗎?顯然第一個空閑塊大小不夠。mIL28資訊網——每日最新資訊28at.com
圖片mIL28資訊網——每日最新資訊28at.com
第二個呢,第二個也不夠。mIL28資訊網——每日最新資訊28at.com
圖片mIL28資訊網——每日最新資訊28at.com
但是你發現了一個問題,仔細看著兩個空閑塊,這兩個空閑塊的總大小實際上是超過D的。mIL28資訊網——每日最新資訊28at.com
圖片mIL28資訊網——每日最新資訊28at.com
我們把這種空閑的但是不能用來分配出去的內存稱之為內存碎片。mIL28資訊網——每日最新資訊28at.com
圖片mIL28資訊網——每日最新資訊28at.com
你可以想象一下經過不斷的內存申請和釋放,堆區中會存在無數這樣空閑內存碎片。mIL28資訊網——每日最新資訊28at.com
圖片mIL28資訊網——每日最新資訊28at.com
碎片化的內存顯然不利于內存的充分利用,計算機科學歷史上有無數論文試圖來解決這個問題。mIL28資訊網——每日最新資訊28at.com
現在堆區已經不足以為D申請出內存,該怎么辦呢?mIL28資訊網——每日最新資訊28at.com
讓我們回到最初的布局,注意看堆區和棧區中間實際上還有一段空閑內存區域,這塊區域就是為堆區或棧區來擴大地盤用的,那么該怎么擴大堆區呢?mIL28資訊網——每日最新資訊28at.com
圖片mIL28資訊網——每日最新資訊28at.com
這就要借助操作系統的幫助了。mIL28資訊網——每日最新資訊28at.com
在linux等系統中可以借助brk等系統調用向操作系統申請來擴大堆區。mIL28資訊網——每日最新資訊28at.com
圖片mIL28資訊網——每日最新資訊28at.com
mIL28資訊網——每日最新資訊28at.com
現在堆區擴容完畢,此時就可以在堆區中找出一塊合適的空閑內存分配給D,到這時malloc這個過程才真正結束,這實際上是一個相當復雜的過程。mIL28資訊網——每日最新資訊28at.com
圖片 mIL28資訊網——每日最新資訊28at.com
本文鏈接:http://www.tebozhan.com/showinfo-26-96829-0.html內存是怎樣一步步被分配出來的?
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com
上一篇: 高通中國區董事長孟樸:攜手生態伙伴,共創數智時代下的新增長機遇
下一篇: 最高優惠 300 元,小米 Civi 4 Pro 手機開啟“暑期特惠”:驍龍 8s Gen3,2799 元起