malloc和new出來的地址都是虛擬地址 你就說內存管理單元怎么可能讓你直接操作硬件內存地址!


malloc的實現與物理內存自然是無關的,內核為每個進程維護一張頁表,頁表存儲進程空間內每頁的虛擬地址,頁表項中有的虛擬內存頁對應着某個物理內存頁面,也有的虛擬內存頁沒有實際的物理頁面對應。無論malloc通過sbrk還是mmap實現,分配到的內存只是虛擬內存,而且只是虛擬內存的頁號,代表這塊空間進程可以用,實際上還沒有分配到實際的物理頁面。等你的進程訪問到這個新分配的內存空間的時候,如果其還沒有對應的物理頁面分配,就會產生缺頁中斷,內核這個時候會給進程分配實際的物理頁面,以與這個未被映射的虛擬頁面對應起來,然后程序就可以歡快的繼續往下跑了。



摘自:https://www.zhihu.com/question/20220583/answer/28490955

 

malloc是一個庫函數,不同的操作系統上具體實現細節是不同的,以下就以linux條件下進行分析:linux采用的是glibc中堆內存管理ptmalloc實現,虛擬內存的布局規定了malloc申請位置以及大小,malloc一次性能申請小內存(小於128KB),分配的是在堆區(heap),用sbrk()進行對齊生長,而malloc一次性申請大內存(大於128KB時)分配到的是在映射區,而不是在堆區,采用的mmap()系統調用進行映射。當然虛擬地址只是規定了一種最理想的狀態,實際分配還是要考慮到物理內存加交換內存總量的限制,因為每次分配,特別是大內存分配采用mmap()映射內存需要記錄物理內存加交換內存地址,所有物理內存加交換內存限制了malloc實際分配。比如32位情況下,最新版本的linux的映射區在用戶空間區的3G位置,而映射區向下生長,所以理想情況下大概能有2.9GB(除去開始地址128M),如果你的物理內存加交換區只有2G,malloc一次申請最多1.8G左右,如果你的物理內存加交換區大於4G,那么最多能有2.9G或者2.8G左右。網上能找到測試代碼的。



摘自:https://www.zhihu.com/question/20220583/answer/22913516


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM