午夜网站国产欧美_加勒比视频亚洲无码_91亚洲人人在字幕国产_18禁止美女爆乳免费网站_被消防员c哭高h野外糙汉动漫_午夜精品视频在线无码_gogowww人体大胆裸体午液_2021自拍偷区亚洲综合第一页_国产欧美一区二区精品性色超碰_99國產精品無碼

Hi,您好,歡迎來(lái)到西安盛圖軟件科技有限公司!

Linux 如何進(jìn)行內(nèi)存分配

發(fā)布時(shí)間:2023-10-19 16:48:15

虛擬內(nèi)存管理回顧

在 Linux 操作系統(tǒng)中,虛擬地址空間的內(nèi)部又被分為內(nèi)核空間和用戶空間兩部分,不同位數(shù)的系統(tǒng),地址空間的范圍也不同。比如最常見的 32 位和 64 位系統(tǒng),如下所示:



通過這里可以看出:


再來(lái)說說,內(nèi)核空間與用戶空間的區(qū)別:


雖然每個(gè)進(jìn)程都各自有獨(dú)立的虛擬內(nèi)存,但是每個(gè)虛擬內(nèi)存中的內(nèi)核地址,其實(shí)關(guān)聯(lián)的都是相同的物理內(nèi)存。這樣,進(jìn)程切換到內(nèi)核態(tài)后,就可以很方便地訪問內(nèi)核空間內(nèi)存。



我們看看用戶空間分布的情況,以 32 位系統(tǒng):



通過這張圖你可以看到,用戶空間內(nèi)存,從低到高分別是 6 種不同的內(nèi)存段:

申請(qǐng)內(nèi)存的兩種方式

申請(qǐng)內(nèi)存空間一般就兩種方法,一種是 malloc,另一種是 mmap 映射空間。 在使用 malloc()分配內(nèi)存的時(shí)候,可能系統(tǒng)調(diào)用 brk(),也可能調(diào)用 mmap()。

malloc 的調(diào)用規(guī)律

1. 即分配一塊小型內(nèi)存(小于或等于 128kb),malloc()會(huì)調(diào)用 brk 函數(shù)將 堆頂 指針向高地址移動(dòng),獲得新的內(nèi)存空間。

2. 當(dāng)分配一塊大型內(nèi)存(大于 128kb),mmap() 系統(tǒng)調(diào)用中「私有匿名映射」的方式,在文件映射區(qū)分配一塊內(nèi)存

申請(qǐng)內(nèi)存過程圖

需要注意的是,malloc() 分配的是虛擬內(nèi)存。


如果分配后的虛擬內(nèi)存沒有被訪問的話,虛擬內(nèi)存是不會(huì)映射到物理內(nèi)存的,這樣就不會(huì)占用物理內(nèi)存了。

只有在訪問已分配的虛擬地址空間的時(shí)候,操作系統(tǒng)通過查找頁(yè)表,發(fā)現(xiàn)虛擬內(nèi)存對(duì)應(yīng)的頁(yè)沒有在物理內(nèi)存中,就會(huì)觸發(fā)缺頁(yè)中斷,然后操作系統(tǒng)會(huì)建立虛擬內(nèi)存和物理內(nèi)存之間的映射關(guān)系。


缺頁(yè)中斷就是要訪問的頁(yè)不在主存,需要操作系統(tǒng)將其調(diào)入主存后再進(jìn)行訪問。在這個(gè)時(shí)候,被內(nèi)存映射的文件實(shí)際上成了一個(gè)分頁(yè)交換文件。

malloc 申請(qǐng)的內(nèi)存,free 釋放內(nèi)存會(huì)歸還給操作系統(tǒng)嗎

mmap 和 brk 分配內(nèi)存的區(qū)別

mmap 來(lái)分配內(nèi)存的問題

mmap 分配的內(nèi)存每次釋放的時(shí)候,都會(huì)歸還給操作系統(tǒng),于是每次 mmap 分配的虛擬地址都是缺頁(yè)狀態(tài)的,然后在第一次訪問該虛擬地址的時(shí)候,就會(huì)觸發(fā)缺頁(yè)中斷。


也就是說,頻繁通過 mmap 分配的內(nèi)存話,不僅每次都會(huì)發(fā)生運(yùn)行態(tài)的切換,還會(huì)發(fā)生缺頁(yè)中斷(在第一次訪問虛擬地址后),這樣會(huì)導(dǎo)致 CPU 消耗較大。


為了改進(jìn)這兩個(gè)問題,malloc 通過 brk() 系統(tǒng)調(diào)用在堆空間申請(qǐng)內(nèi)存的時(shí)候,由于堆空間是連續(xù)的,所以直接預(yù)分配更大的內(nèi)存來(lái)作為內(nèi)存池,當(dāng)內(nèi)存釋放的時(shí)候,就緩存在內(nèi)存池中。


等下次在申請(qǐng)內(nèi)存的時(shí)候,就直接從內(nèi)存池取出對(duì)應(yīng)的內(nèi)存塊就行了,而且可能這個(gè)內(nèi)存塊的虛擬地址與物理地址的映射關(guān)系還存在,這樣不僅減少了系統(tǒng)調(diào)用的次數(shù),也減少了缺頁(yè)中斷的次數(shù),這將大大降低 CPU 的消耗。

只使用 brk 來(lái)分配內(nèi)存的問題

前面我們提到通過 brk 從堆空間分配的內(nèi)存,并不會(huì)歸還給操作系統(tǒng),那么我們那考慮這樣一個(gè)場(chǎng)景。

如果我們連續(xù)申請(qǐng)了 10k,20k,30k 這三片內(nèi)存,如果 10k 和 20k 這兩片釋放了,變?yōu)榱丝臻e內(nèi)存空間,如果下次申請(qǐng)的內(nèi)存小于 30k,那么就可以重用這個(gè)空閑內(nèi)存空間。



但是如果下次申請(qǐng)的內(nèi)存大于 30k,沒有可用的空閑內(nèi)存空間,必須向 OS 申請(qǐng),實(shí)際使用內(nèi)存繼續(xù)增大。


因此,隨著系統(tǒng)頻繁地 malloc 和 free ,尤其對(duì)于小塊內(nèi)存,堆內(nèi)將產(chǎn)生越來(lái)越多不可用的碎片,導(dǎo)致“內(nèi)存泄露”。而這種“泄露”現(xiàn)象使用 valgrind 是無(wú)法檢測(cè)出來(lái)的。


所以,malloc 實(shí)現(xiàn)中,充分考慮了 brk 和 mmap 行為上的差異及優(yōu)缺點(diǎn),默認(rèn)分配大塊內(nèi)存 (128KB) 才使用 mmap 分配內(nèi)存空間。


上一篇:嵌入式系統(tǒng)和C語(yǔ)言
下一篇:學(xué)習(xí)方法|學(xué)習(xí)嵌入式的十個(gè)小技巧

歡迎登錄盛圖科技

歡迎注冊(cè)盛圖科技

已有賬號(hào),立即登錄