由malloc等函數想到的一些問題

malloc/calloc函數作用都是在堆上分配內存,區別是malloc函數分配好內存後沒有初始化內存,而calloc函數分配好函數後會把內存清零。還有一個alloca函數是在棧上分配內存。

之前個人總是想當然的認爲malloc函數是系統調用,它的流程是向操作系統申請內存, 操作系統在內核空間分配好內存後調用內核態類似mmap的函數映射到用戶進程空間。後來想到malloc是C庫函數,發現我理解錯了。malloc函數會調用brk/sbrk, 用來改變進程數據段的基址和大小。這麼說來, malloc等函數分配的是線性地址,需要的時候由內核映射成物理地址。

提到線性地址不得不說分段機制和分頁機制兩種內存管理機制。

分段機制是早期的內存管理機制,所謂分段就是將一塊可執行文件大小的邏輯內存映射成物理內存。我總是將內存分段機制中的段和我們學習x86實模式下的彙編中的段弄混淆,分段內存管理中段是一塊與可執行文件的大小相同的物理內存。這塊物理內存的段基址由系統負責映射。而intel x86的彙編語言中的代碼段 數據段等也是分塊思想(他們對應的是elf格式中的段,或者節),它們都是邏輯地址,由操作系統映射成物理地址,這些邏輯段最終都在一個物理段內。

分頁機制是把物理內存和線性內存分成大小相同的塊(一般是4k),  如果線性內存很大(32位系統就是4G), 這些塊則非常多,查找效率較低,這時需要對一些地址範圍做索引形成頁表。這種機制分配內存的時候只會給進程分配可執行文件大小的線性內存,真正使用的時候纔會將邏輯內存映射到物理內存。一開始可能只映射.text節的前4k字節,運行的時候CPU如果發現了邏輯地址沒有映射,向系統報一個缺頁中斷,系統將該頁映射成物理內存。隨着程序的不斷運行,越來越多的邏輯內存被映射。

在之前沒有內存管理時,這兩種機制都解決了以下3個問題:

1. 進程間的內存隔離, 應用使用的都是虛擬地址,一個應用進程不能隨意訪問另一個應用進程的內存空間, 因爲映射機制對應用是不可見的,應用進程不知道自己的物理內存,也不知其他進程的物理內存。

2. 內存不夠時,可以置換出沒有運行進程的內存,分段機制置換的大小是以進程爲單位進行置換, 分頁機制以頁爲單位。通常頁的尺寸比段小。

分頁是一種更小粒度的內存管理,根據局部原理,採用分頁機制,換入換出的效率更高,進程運行時需要的物理內存更小。

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