malloc實現原理
- malloc是什么?
- malloc,calloc, realloc的區別
- malloc的實現原理
- malloc的兩種實現方式
- 為什么使用brk?
- 為什么使用mmap?
- malloc怎么定界的
- malloc分配的是虛擬內存上的空間嗎?
malloc是什么?
??通過malloc,我們可以開辟一個自定義大小的內存空間。
??通過上圖我們可以知道,malloc是一個C的庫函數,參數是分配一個size大小(正整數)的空間,分配成功后返回一個void*
指針,說明可以通過強轉,返回一個任意類型的指針。分配空間失敗后返回null
。
malloc,calloc, realloc的區別
??根據上圖來說明:
- malloc: 分配size字節大小的空間,分配空間成功后返回一個
void*
指針;分配空間失敗后返回null
。 - calloc: 分配num個size字節大小的空間,分配空間成功后返回一個
void*
指針;分配空間失敗后返回null
。 - realloc: 對ptr指針指向的空間,將其大小改變為size字節大小。成功后返回一個
void*
指針;失敗后返回null
。具體可以參考博客:realloc的用法。
malloc的實現原理
?? malloc是C庫函數,所以底層肯定使用系統調用來實現。
?? malloc分配內存的時候,會預分配一個更大的空間作為內存池,然后在內存池上面劃分所申請大小的空間并返回,free時也不會將空間直接釋放,而是將空間歸還給內存池。但通過后面我們可以知道,只有當底層使用brk時才是這樣的,使用mmap時直接分配內存,free后就還給OS,不會和內存池產生交互。
malloc的兩種實現方式
malloc通過以下兩個系統調用來實現:
- brk: 當分配的空間大小 小于 128KB時, 在堆上分配空間。
- mmap: 當分配的空間大小 大于 128KB時, 在文件映射區上分配空間。
為什么使用brk?
?? 當分配的空間大小 小于 128KB時, 在堆上分配空間。為什么這樣設計呢?
?? 因為mmap使用完內存free會直接釋放歸還給操作系統,頻繁的調用mmap會使得用戶態和內核態來回切換,會降低效率,于是利用了內存池來解決這個問題,每次調用brk函數都會預分配更大的空間來放入內存池,下一次在調用brk的時候,就可以不用切換為內核態,直接將內存池的空間分配即可,提高了效率。
為什么使用mmap?
?? 為什么使用mmap呢?
??因為brk在內存池中的釋放空間和申請空間都會造成許多內存碎片,如果我們頻繁申請很多大空間的內存,如果都使用brk,就會造成內存池中出現許多空間大的內存碎片,造成了空間浪費。
??所以,當我們申請小空間的內存時,使用brk,將其放入內存池,就算形成內存碎片也不會造成很大的空間浪費, 而且減少了內核態和用戶態的切換,提高了效率。當我們申請大空間的內存時,使用mmap,就能避免內存池中沒有合適大小的空間,并且free后直接釋放給了操作系統,避免了造成更大的空間浪費。
malloc怎么定界的
?? malloc分配空間時,會返回一個指向所申請空間開頭地址的指針,那么只靠這一個指針,是怎么分辨分配空間的界限的呢?怎么知道空間有多大呢?
??原因是因為malloc在分配內存時,多分配了一段內存空間,其中存儲了用戶所需空間的大小,有了這個我們就能確定界限。這段多分配的空間就在malloc返回的指針指向地址的前面的空間處。如圖:
malloc分配的是虛擬內存上的空間嗎?
??malloc分配的是虛擬內存上的空間,一開始并不會在物理內存上面分配內存,當我們使用這個空間的時候,拿到這個虛擬地址,去頁表查詢,會發現沒有對應的頁表項,就會觸發缺頁中斷,然后操作系統在物理內存分配相應大小的空間,更新頁表,再重新查詢,這時候,才會真正的在物理內存上分配內存。
??所以,如果一直使用mmap,每次都釋放空間給操作系統,頁表中的頁表項也會被刪除,再進行申請空間的, 使用空間的時候,就會造成缺頁中斷,造成效率低下。而使用brk不會將內存空間返還給操作系統,頁表中這個已經free的空間和物理內存頁面的映射關系可能還在,下次申請空間時就不會造成缺頁中斷。
???????新人創作不易,你的點贊和關注都是對我莫大的鼓勵,再次感謝您的觀看。