linux內存管理(中),匿名存儲段映射

glibc 的內存分配使用了數據段和內存映射。實現malloc最經典的方法就是將數據段分爲一系列大小爲2的冪的塊,返回最小的複合要求的塊來滿足請求。釋放則只是簡單的將這塊區域標記爲未使用。如果相鄰的分區都是空閒的,他們會被合稱一個更大的分區。如果堆的最頂端是空的,可以用brk來降低斷電,使堆收縮,將內存返回給系統。

這種算法叫做夥伴內存算法,他的有點是告訴和簡單,缺點是會產生兩種類型的內存碎片。當使用的內存塊大於請求的大小的時候則會產生內存碎片。這導致了內存的地使用率。外部碎片則是在空閒存儲器合計起來足夠滿足一個請求,但是沒有一個單獨的空間塊可以來處理這個請求時候發生的。這同樣會導致內存利用不足,因爲可能會分配一個更大的塊,或者是分配失敗。

內存管理夥伴算法:

https://blog.csdn.net/jy1075518049/article/details/43911183

因此對於比較大的分配,glibc並不使用堆麼事創建一個匿名內存映射來滿足要求。匿名存儲器映射在第四章討論的基於文件的映射十分相似,只是他並不是基於文件,所以我們稱之爲匿名,實際上一個匿名內存映射只是一塊已經用0初始化大的內存塊,以提供給用戶使用。因爲這種映射不是基於堆的所以不會產生內存碎片。

匿名映射的好處:

1.無需關心碎片。當程序不在需要這塊內存的時候,只要撤銷映射,這塊內存就直接歸還給系統了。

2.匿名存儲映射的大小是可以調整的,可以設置權限,還能像普通的映射一樣接收建議。

3.每個分配存在於獨立的內存映射。沒有必要再去管理一個全局的堆了


使用匿名內存映射與堆比起來有兩個缺點:

每個存儲器映射都是頁面大小的整數倍。所以如果大小不是頁面的整數倍會造成很大的空間浪費,對於比較小的分配來說空間的浪費會更加的顯著,因爲相對於使用的空間,浪費的空間會更大。

創建一個新的內存映射比從堆中返回內存的負載要打,因爲使用堆幾乎不涉及任何內核操作。越小的分配,這樣的問題也就越明顯。越小的分配,這樣的問題也就越明顯。

根據各自的優缺點來判斷,glibc的malloc使用數據段來滿足小的分配,而匿名內存映射則用來滿足大的分配。兩者的臨界點是可以調的,並且會隨着glibc版本的不同而發生變化。目前,臨界點一般是128kb;比128kb小的分配由堆來實現,較大的由匿名存儲映射來實現

####8.4.1創建匿名存儲映射
或許你再某次分配想使用一個內存映射而不是堆,那麼你可以使用mmap和unmmap來銷燬

```
#include <sys/mman.h>
void* mmap(void* start,size_t length,int port,int flags,int fd,off_t offset);
int munmap(void* offset);
```

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章