成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

Linux用戶態(tài)進程的內(nèi)存管理

2021-02-19    分類: 網(wǎng)站建設(shè)

上一篇我們了解了內(nèi)存在內(nèi)核態(tài)是如何管理的,本篇文章我們一起來看下內(nèi)存在用戶態(tài)的使用情況,如果上一篇文章說是內(nèi)核驅(qū)動工程師經(jīng)常面對的內(nèi)存管理問題,那本篇就是應(yīng)用工程師常面對的問題。

相信大家都知道對用戶態(tài)的內(nèi)存消耗對象是進程,應(yīng)用開發(fā)者面對的所有代碼操作最后的落腳點都是進程,這也是說為什么內(nèi)存和進程兩個知識點的重要性,理解了內(nèi)存和進程兩大法寶,對所有軟件開發(fā)的理解都會有了全局觀(關(guān)于進程的知識以后再整理和大家分享)。

下面閑話少說,開始本篇的內(nèi)容——進程的內(nèi)存消耗和泄漏


進程的虛擬地址空間VMA(Virtual Memory Area)

在linux操作系統(tǒng)中,每個進程都通過一個task_struct的結(jié)構(gòu)體描敘,每個進程的地址空間都通過一個mm_struct描敘,c語言中的每個段空間都通過vm_area_struct表示,他們關(guān)系如下 :

上圖中,task_struct中的mm_struct就代表進程的整個內(nèi)存資源,mm_struct中的pgd為頁表,mmap指針指向的vm_area_struct鏈表的每一個節(jié)點就代表進程的一個虛擬地址空間,即一個VMA。一個VMA最終可能對應(yīng)ELF可執(zhí)行程序的數(shù)據(jù)段、代碼段、堆、棧、或者動態(tài)鏈接庫的某個部分。

VMA的分布情況可以有通過pmap命令,及maps,smaps文件查看,如下圖:

另,VMA的具體內(nèi)容可參考下圖。


page fault的幾種可能性

我們先來看張圖:

(此圖來源于宋寶華老師)

  • 如,調(diào)用malloc申請100M內(nèi)存,IA32下在0~3G虛擬地址中立刻就會占用到大小為100M的VMA,且符合堆的定義,這一段VMA的權(quán)限是R+W的。但由于Lazy機制,這100M其實并沒有獲得,這100M全部映射到一個物理地址相同的零頁,且在頁表中記錄的權(quán)限為只讀的。當100M中任何一頁發(fā)生寫操作時,MMU會給CPU發(fā)page fault(MMU可以從寄存器讀出發(fā)生page fault的地址;MMU可以讀出發(fā)生page fault的原因),Linux內(nèi)核收到缺頁中斷,在缺頁中斷的處理程序中讀出虛擬地址和原因,去VMA中查,發(fā)現(xiàn)是用戶程序在寫malloc的合法區(qū)域且有寫權(quán)限,Linux內(nèi)核就真正的申請內(nèi)存,頁表中對應(yīng)一頁的權(quán)限也修改為R+W。

  • 如,程序中有野指針飛到了此程序運行時進程的VMA以外的非法區(qū)域,硬件就會收到page fault,進程會收到SIGSEGV信號報段錯誤并終止。如,程序中有野指針飛到了此程序運行時進程的VMA以外的非法區(qū)域,硬件就會收到page fault,進程會收到SIGSEGV信號報段錯誤并終止。

  • 如,代碼段在VMA中權(quán)限為R+X,如果程序中有野指針飛到此區(qū)域去寫,則也會發(fā)生段錯誤。(另,malloc堆區(qū)在VMA中權(quán)限為R+W,如果程序的PC指針飛到此區(qū)域去執(zhí)行,同樣發(fā)生段錯誤。)

  • 如,執(zhí)行代碼段時會發(fā)生缺頁,Linux申請1頁內(nèi)存,并從硬盤讀取出代碼段,此時產(chǎn)生了IO操作,為major主缺頁。如,執(zhí)行代碼段時會發(fā)生缺頁,Linux申請1頁內(nèi)存,并從硬盤讀取出代碼段,此時產(chǎn)生了IO操作,為major主缺頁。

(此圖來源于宋寶華老師)

綜上,page fault后,Linux會查VMA,也會比對VMA中和頁表中的權(quán)限,體現(xiàn)出VMA的重要作用。


malloc分配的原理

malloc的過程其實就是把VMA分配到各種段當中,這時候是沒有真正分配物理地址的。malloc 調(diào)用后,只是分配了內(nèi)存的邏輯地址,在內(nèi)核的mm_struct 鏈表中

  • malloc小于128k的內(nèi)存,使用brk分配內(nèi)存,將_edata往高地址推(只分配虛擬空間,不對應(yīng)物理內(nèi)存(因此沒有初始化),第一次讀/寫數(shù)據(jù)時,引起內(nèi)核缺頁中斷,內(nèi)核才分配對應(yīng)的物理內(nèi)存,然后虛擬地址空間建立映射關(guān)系)

  • malloc大于128k的內(nèi)存,使用mmap分配內(nèi)存,在堆和棧之間找一塊空閑內(nèi)存分配(對應(yīng)獨立內(nèi)存,而且初始化為0)


    • 內(nèi)存的消耗VSS RSS PSS USS

      首先,我們評估一個進程的內(nèi)存消耗都是指用戶空間的內(nèi)存,不包括內(nèi)核空間的內(nèi)存消耗 。這里我們用工具 procrank先來看下Linux進程的內(nèi)存占用量 。

      • VSS -Virtual Set Size 虛擬耗用內(nèi)存(包含共享庫占用的內(nèi)存)

      • RSS -Resident Set Size 實際使用物理內(nèi)存(包含共享庫占用的內(nèi)存)

      • PSS -Proportional Set Size 實際使用的物理內(nèi)存(比例分配共享庫占用的內(nèi)存)

      • USS -Unique Set Size 進程獨自占用的物理內(nèi)存(不包含共享庫占用的內(nèi)存)

      下面再用一張圖來更好的解釋VSS,RSS,PSS,USS之間的區(qū)別:

      有了對VSS,RSS,PSS,USS的了解,我們趁熱打鐵來看下內(nèi)存在進程中是如何被瓜分的:

      (此圖來源于宋寶華老師)

      1044,1045,1054三個進程,每個進程都有一個頁表,對應(yīng)其虛擬地址如何向real memory上去轉(zhuǎn)換。

      process 1044的1,2,3都在虛擬地址空間,所以其VSS=1+2+3。

      process 1044的4,5,6都在real memory上,所以其RSS=4+5+6。

      分析real memory的具體瓜分情況:

      4 libc代碼段,1044,1045,1054三個進程都使用了libc的代碼段,被三個進程分享。

      5 bash shell的代碼段,1044,1045都是bash shell,被兩個進程分享。

      6 1044獨占

      所以,上圖中4+5+6并不全是1044進程消耗的內(nèi)存,因為4明顯被3個進程指向,5明顯被2個進程指向,衍生出了PSS(按比例計算的駐留內(nèi)存)的概念。進程1044的PSS為4/3 +5/2 +6。

      最后,進程1044獨占且駐留的內(nèi)存USS為 6。

      一般來說內(nèi)存占用大小有如下規(guī)律:VSS >= RSS >= PSS >= USS

      本文名稱:Linux用戶態(tài)進程的內(nèi)存管理
      瀏覽地址:http://jinyejixie.com/news8/101808.html

      成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站策劃、網(wǎng)站導航品牌網(wǎng)站設(shè)計、建站公司、響應(yīng)式網(wǎng)站、網(wǎng)站收錄

      廣告

      聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

      網(wǎng)站建設(shè)網(wǎng)站維護公司
      邛崃市| 绍兴县| 太保市| 许昌县| 紫云| 茂名市| 平陆县| 临海市| 连城县| 临海市| 潜山县| 克山县| 广平县| 洛南县| 丹棱县| 晋江市| 友谊县| 边坝县| 吉安县| 礼泉县| 郯城县| 介休市| 天等县| 读书| 安远县| 石景山区| 隆子县| 广宗县| 岫岩| 洮南市| 新巴尔虎右旗| 育儿| 长子县| 大同县| 夹江县| 会理县| 田林县| 瑞安市| 定兴县| 安塞县| 长兴县|