linux 共享内存_什么是物理/虚拟/共享内存——Linux内存管理小结一
物理內存和虛擬內存到底有什么區別?
提到內存,我們會想到經常接觸的三個詞:虛擬內存、物理內存、共享內存。它們分別對應top輸出中的VIRT、RES、SHR三列。
1. 物理內存
系統的物理內存被劃分為許多相同大小的部分,也稱作內存頁。內存頁的大小取決于CPU的架構和操作系統的配置,一般為4KB。物理內存的使用主要分為以下幾方面:
(1)內核使用
操作系統啟動時,位于/boot目錄下的壓縮內核文件會被加載到內存中并解壓。這部分內容在系統允許期間都會常駐在內存的起始位置。
(2)slab分配器
操作系統的運行還需要更多的空間來分配給管理進程、文件描述符、socket和加載的內和模塊等內容。所以內核會通過slab分配器動態分配內存。
PS:slab是Linux操作系統的一種內存分配機制。其工作是針對一些經常分配并釋放的對象,如進程描述符等,這些對象的大小一般比較小,如果直接采用brk系統調用來進行分配和釋放,不僅會造成大量的碎片,而且也會影響性能。而slab分配器是基于對象進行管理的,相同類型的對象歸為一類(如進程描述符就是一類),每當要申請這樣一個對象,slab分配器就從一個slab列表中分配一個這樣大小的單元出去,而當要釋放時,將其重新保存在該列表中,而不是直接返回給操作系統,從而避免這些出現內存碎片。slab分配器并不丟棄已分配的對象,而是釋放并把它們保存在內存中。當以后又要請求新的對象時,就可以從內存直接獲取而不用重復初始化。可以在/proc/meminfo中查看當前slab分配器中的內存大小。
(3)進程使用
除去內核使用的部分,所有的進程都需要分配物理內存頁給它們的代碼、數據和堆棧。進程消耗的這些物理內存被稱為“駐留內存”,RSS。
(4)頁緩存page cache
除去在內核和進程使用的部分,物理內存剩下的部分被稱為頁緩存,page cache。因為磁盤io的速度遠遠低于內存的訪問速度,所以為了加快訪問磁盤數據的速度,頁緩存盡可能的保存著從磁盤讀入的數據。page cache中還有一部分稱為buffer,它的作用是緩存要寫入到磁盤的數據。
頁緩存的大小是在一直動態變化的。當系統內存充足時,頁緩存會一直增大;當系統free內存不足時,這時如果有進程申請內存,操作系統會從page cache中回收內存頁進行分配,如果page cache也已不足,那么系統會將當期駐留在內存中的數據置換到事先配置在磁盤上的swap空間中,然后空出來的這部分內存就可以用來分配了。這就是swap交換。
PS:出現swap交換時,數據被置換到swap空間后(swap out),該進程使用的內存量下降,在atop等監控工具中的RGROW列為負值,但這并不表示該進程釋放了內存,當它需要時,這部分數據又會被換入到內存中(swap in)。另外, swap交換往往會帶來磁盤IO的大量消耗,嚴重影響到系統正常的磁盤io。出現大量的swap交換說明系統已經快要不行了,需要重點關注。
2. 虛擬內存
顧名思義,虛擬內存實際上并不存在,它只是存在于這套巧妙的內存管理機制中。當一個進程啟動時,內核會給新的進程建立一個虛擬地址空間。這個虛擬地址空間代表了該進程可能使用到的所有內存,當然它是可以動態變化的。虛擬地址結構示意圖如下,從下往上地址增大,主要包括以下幾個部分:
(1)代碼段:該部分只讀,用于存放加載的代碼。
(2)數據段:用于存放全局變量和靜態變量。
(3)堆:動態內存,當malloc/free申請釋放內存小于某個閾值(一般操作系統設定為128K,可以修改)時,通過brk/sbrk系統調用,控制堆頂指針向高地址偏移(malloc)或者低地址偏移(free)。
(4)文件映射區:動態內存,當malloc/free申請釋放內存大于128K時,通過mmap系統調用分配一塊虛擬地址空間。
(5)棧:用于存放局部變量和進程上下文。
看到這里可能會產生一個疑問:既然都有了物理內存,為什么還要有虛擬內存呢?這是因為由于成本的限制,物理內存往往無法做的很大,但是進程運行階段所需申請的內存可能遠遠超過物理內存,并且系統不可能只跑一個進程,會有多個進程一起申請使用內存,如果都直接向物理內存進行申請使用肯定無法滿足。通過引入虛擬內存,每個進程都有自己獨立的虛擬地址空間,這個空間理論上可以無限大,因為它并不要錢。一個進程同一時刻不可能所有變量數據都會訪問到,只需要在訪問某部分數據時,把這一塊虛擬內存映射到物理內存,其他沒有實際訪問過的虛擬地址空間并不會占用到物理內存,這樣對物理內存的消耗就大大減少了 。
虛擬內存->物理內存的映射機制
系統內核為每個進程都維護了一份從虛擬內存到物理內存的映射表,稱為頁表。頁表根據虛擬地址,查找出鎖映射的物理頁位置和數據在物理頁中的偏移量,便得到了實際需要訪問的物理地址。(具體的多級頁表實現本文不深入探討)
如下圖所示:
這里還要提到一個概念,駐留內存,這是指虛擬內存中實際映射到物理內存的那部分,也就是進程實際占用的物理內存大小。所以判斷一個進程使用的內存大小,主要是看占用的物理內存,也就是駐留內存的大小,即RSS。
3. 共享內存
進程在運行過程中,會加載許多操作系統的動態庫,比如 libc.so、libld.so等。這些庫對于每個進程而言都是公用的,它們在內存中實際只會加載一份,這部分稱為共享內存。如上圖中的A4和B3部分即為共享內存,實際都映射到同一塊物理內存。
注意,進程占用的共享內存也是計算到駐留內存中的。
另外關于c++ Linux后臺服務器開發的一些知識點分享:Linux,Nginx,MySQL,Redis,P2P,K8S,Docker,TCP/IP,協程,DPDK,webrtc,音視頻等等視頻。
喜歡的朋友可以后臺私信【1】獲取學習視頻
總結
以上是生活随笔為你收集整理的linux 共享内存_什么是物理/虚拟/共享内存——Linux内存管理小结一的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 嵌入式处理器 cisc risc_RIS
- 下一篇: linux下c语言http服务器_服务器