<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          內(nèi)存是怎樣一步步被分配出來的?

          共 2665字,需瀏覽 6分鐘

           ·

          2024-06-27 11:50

          Python客棧設(shè)為“星標(biāo)?
          第一時(shí)間收到最新資訊

          大家好,今天簡單聊聊內(nèi)存分配。
          我們申請一塊內(nèi)存時(shí)計(jì)算機(jī)內(nèi)部發(fā)生了什么?下這句代碼:
          這里有兩部分,一個(gè)是malloc,再一個(gè)是你寫的代碼。
          malloc實(shí)際上屬于標(biāo)準(zhǔn)庫,標(biāo)準(zhǔn)庫里有什么呢?
          數(shù)學(xué)相關(guān)的函數(shù),sin、cos、絕對(duì)值、數(shù)冪函數(shù)等;字符相關(guān)函數(shù),判斷大小寫等;字符串操作函數(shù)、字符串拷貝、拼接比較等;當(dāng)然還有內(nèi)存管理函數(shù),就是這里提到的malloc/free,當(dāng)然還有很多其它函數(shù),這就是標(biāo)準(zhǔn)庫。
          再來看你寫的代碼,什么是你寫的代碼呢?以c語言為例,.c文件就是你寫的代碼,這包括你寫的hello world程序、充滿bug的練習(xí)程序,當(dāng)然還有各種項(xiàng)目。

          這就是你寫的代碼。
          這些代碼怎么變成最終的可執(zhí)行程序呢?當(dāng)然是借助編譯器。
          編譯器會(huì)把你的代碼編譯成目標(biāo)文件。

          接著鏈接器出場,連接器會(huì)把目標(biāo)文件和標(biāo)準(zhǔn)庫打包成可執(zhí)行程序。

          這就是代碼部分,接下來我們看內(nèi)存分配。
          到底什么是內(nèi)存呢?

          內(nèi)存實(shí)際上和儲(chǔ)物柜非常相似,儲(chǔ)物柜會(huì)劃分成了一個(gè)一個(gè)大小相同的隔間,每個(gè)隔間可以存儲(chǔ)東西,內(nèi)存的道理也一樣,內(nèi)存也被劃分成了一個(gè)一個(gè)大小相同的隔間,我們來仔細(xì)看一下。

          內(nèi)存中的每個(gè)隔間存儲(chǔ)的是一個(gè)字節(jié),8比特位一字節(jié)。
          比如這里申請的一塊int大小的內(nèi)存,一個(gè)int占據(jù)4個(gè)字節(jié)。

          和儲(chǔ)物柜一樣,內(nèi)存中的每個(gè)隔間也有一個(gè)編號(hào),這個(gè)編號(hào)叫做內(nèi)存地址。
          在我們的實(shí)例中,申請的這塊內(nèi)存位于內(nèi)存地址2這個(gè)位置,這意味著什么嗯?這意味著變量p等于數(shù)字2,或者說等于內(nèi)存地址2,這里的p就是所謂的指針。

          接著我們看內(nèi)存分配過程。
          這段代碼當(dāng)然屬于編譯后生成的可執(zhí)行程序,可執(zhí)行程序是在內(nèi)存中運(yùn)行的,當(dāng)然我們需要為整個(gè)程序分配一塊內(nèi)存。

          程序的運(yùn)行依賴棧區(qū),這里存放著局部變量等信息;依賴堆區(qū),這里存放著程序員自己管理的動(dòng)態(tài)申請的內(nèi)存,關(guān)于堆區(qū)和棧區(qū)之前的視頻也有講解;除此之外還依賴代碼區(qū),這里保存的就是編譯后的之類;還有數(shù)據(jù)區(qū),這里保存著全局變量等信息。

          這些區(qū)域在內(nèi)存中的布局是這樣的:

          再次強(qiáng)調(diào)下,編譯后的代碼位于代碼區(qū),malloc動(dòng)態(tài)申請的內(nèi)存位于堆區(qū),接下來我們只關(guān)注堆區(qū)。
          在程序開始運(yùn)行時(shí)堆區(qū)當(dāng)然是空的,那么所謂的內(nèi)存分配到底是什么呢?如果讓你實(shí)現(xiàn)內(nèi)存分配器該怎么做到呢?很簡單,其實(shí)內(nèi)存分配就是劃分地盤。

          此時(shí)要分配第一塊大小為A的內(nèi)存,那么你應(yīng)該把A放在哪里呢?

          因?yàn)榇藭r(shí)堆區(qū)是空的,顯然你可以把開始這個(gè)位置劃分給A,作為A的地盤,找到A的地盤后malloc這個(gè)函數(shù)返回,內(nèi)存分配過程結(jié)束,是不是很簡單。

          接著程序員又開始申請大小為B的內(nèi)存,道理和A一樣,把A之后的地盤給B即可。

          程序員又開始申請大小為C的內(nèi)存,同理。

          接著程序員說A占用的這塊內(nèi)存使用完畢,調(diào)用free釋放,所謂釋放就是把A占據(jù)的地盤重新標(biāo)記為空閑,這時(shí)堆區(qū)里還有兩塊空閑內(nèi)存。

          接著程序員開始申請大小為D,這時(shí)問題來了,你該從哪里給D劃分地盤呢?

          放到第一個(gè)空閑塊嗎?顯然第一個(gè)空閑塊大小不夠。

          第二個(gè)呢,第二個(gè)也不夠。

          但是你發(fā)現(xiàn)了一個(gè)問題,仔細(xì)看著兩個(gè)空閑塊,這兩個(gè)空閑塊的總大小實(shí)際上是超過D的。

          我們把這種空閑的但是不能用來分配出去的內(nèi)存稱之為內(nèi)存碎片。

          你可以想象一下經(jīng)過不斷的內(nèi)存申請和釋放,堆區(qū)中會(huì)存在無數(shù)這樣空閑內(nèi)存碎片。

          碎片化的內(nèi)存顯然不利于內(nèi)存的充分利用,計(jì)算機(jī)科學(xué)歷史上有無數(shù)論文試圖來解決這個(gè)問題。
          現(xiàn)在堆區(qū)已經(jīng)不足以為D申請出內(nèi)存,該怎么辦呢?
          讓我們回到最初的布局,注意看堆區(qū)和棧區(qū)中間實(shí)際上還有一段空閑內(nèi)存區(qū)域,這塊區(qū)域就是為堆區(qū)或棧區(qū)來擴(kuò)大地盤用的,那么該怎么擴(kuò)大堆區(qū)呢?

          這就要借助操作系統(tǒng)的幫助了。
          在linux等系統(tǒng)中可以借助brk等系統(tǒng)調(diào)用向操作系統(tǒng)申請來擴(kuò)大堆區(qū)。

          現(xiàn)在堆區(qū)擴(kuò)容完畢,此時(shí)就可以在堆區(qū)中找出一塊合適的空閑內(nèi)存分配給D,到這時(shí)malloc這個(gè)過程才真正結(jié)束,這實(shí)際上是一個(gè)相當(dāng)復(fù)雜的過程。


          往期回顧

          1、requirements.txt要被拋棄了?
          2、Windows核彈級(jí)漏洞,Win7-Win11全部淪陷!
          3、240萬億巨量數(shù)據(jù)被洗出,足夠訓(xùn)出18個(gè)GPT-4!
          4、提拔你,還是干掉你,從來不是看技術(shù)
          5、彭博社:華為與騰訊接近達(dá)成協(xié)議,不向微信“抽成”
                


          點(diǎn)擊關(guān)注公眾號(hào),閱讀更多精彩內(nèi)容



          瀏覽 59
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲在线电影院日韩 | 依人成人大香蕉天堂黄色 | 成人爽爽 | 亚洲激情视频小说 | 69人妻人人澡人人爽人人精品 |