進程內存分布--之理論知識

一個由C/C++編譯的程序占用的內存分為以下幾個部分 :

1、棧區(stack):由編譯器自動分配釋放 ,存放函數調用函數的參數值,局部變量的值等。其操作方式類似于數據結構中的棧。

2、堆區(heap):一般由程序員分配釋放,如malloc 來分配的全局指針。若程序員不釋放,程序結束時可能由OS回收 。注意它與數據結構中的堆是兩回事,分配方式倒是類似于鏈表,呵呵。

3、全局區(靜態區)(static):全局變量和靜態變量的存儲是放在一塊的,初始化的全局變量和靜態變量在一塊區域,未初始化的全局變量和未初始化的靜態變量在相鄰的另一塊區域。程序結束后有系統釋放。?

4、文字常量區 :常量字符串就是放在這里的。 程序結束后由系統釋放。?

5、程序代碼區:存放函數體的二進制代碼。

  • 進程內存分布總結如下:
  • - 程序段 (Text Segment):可執行文件代碼的內存映射
    • 程序代碼在內存中的映射,存放函數體的二進制代碼。
    • 可執行代碼、字符串字面值、只讀變量
  • - 數據段 (Data Segment):可執行文件的已初始化全局變量的內存映射
    • 在程序運行初已經對變量進行初始化的數據。
    • 已初始化且初值非0的全局變量和局部靜態變量,全局靜態變量,常量
  • - BSS段 (BSS Segment):未初始化的全局變量或者靜態變量(用零頁初始化)
    • 在程序運行初未對變量進行初始化的數據。
    • 未初始化或初值為0的全局變量和靜態局部變量
  • - 堆區 (Heap) : 存儲動態內存分配,匿名的內存映射
    • 存儲動態內存分配,需要程序員手工分配,手工釋放.
    • 注意它與數據結構中的堆是兩回事,分配方式類似于鏈表
  • - 棧區 (Stack) : 進程用戶空間棧,由編譯器自動分配釋放,存放函數的參數值、局部變量的值等
    • 存儲局部、臨時變量,函數參數
    • 函數調用時,存儲函數的返回指針,用于控制函數的調用和返回。
    • 在程序塊開始時自動分配內存,結束時自動釋放內存,其操作方式類似于數據結構中的棧。
    • 但不包括static聲明的變量, static 意味著 在“數據段”中 存放變量
  • - 映射段(Memory Mapping Segment):任何內存映射文件
    • 內核將文件的內容直接映射到內存
    • 內存映射是一種方便高效的文件I/O方式,所以它被用來加載動態庫。創建一個不對應于任何文件的匿名內存映射也是可能的,此方法用于存放程序的數據。
    • 該區域用于映射可執行文件用到的動態鏈接庫。

?????????Linux 對進程地址空間有個標準布局,地址空間中由各個不同的內存段組成 (Memory Segment),主要的內存段如下:圖示如下:

????????Linux 內核將這 4G 字節的空間分為兩部分,將最高的 1G 字節(0xC0000000-0xFFFFFFFF)供內核使用,稱為 內核空間。而將較低的3G字節(0x00000000-0xBFFFFFFF)供各個進程使用,稱為 用戶空間。每個進程可以通過系統調用陷入內核態,因此內核空間是由所有進程共享的。雖然說內核和用戶態進程占用了這么大地址空間,但是并不意味它們使用了這么多物理內存,僅表示它可以支配這么大的地址空間。它們是根據需要,將物理內存映射到虛擬地址空間中使用。

????????在Linux中,內核空間是持續存在的,并且在所有進程中都映射到同樣的物理內存。(Linux內核由系統內的所有進程共享)。

?而上面進程虛擬地址空間中的棧區,正指的是我們所說的進程棧。進程棧的初始化大小是由編譯器和鏈接器計算出來的,但是棧的實時大小并不是固定的,Linux 內核會根據入棧情況對棧區進行動態增長(其實也就是添加新的頁表)。但是并不是說棧區可以無限增長,它也有最大限制 RLIMIT_STACK (一般為 8M),我們可以通過 ulimit 來查看或更改 RLIMIT_STACK 的值。

  • 線程的內存分布

現代 linux 有多線程(linux 的線程其實是個輕量級的進程),一個進程的多個線程之間共享全局變量、堆、打開的文件…,但棧是不能共享的:棧中各層函數幀代表著一條執行線索,一個線程是一條執行線索,所以每個線程獨占一個棧,而這些棧又都必須在所屬進程的內存空間中。進程的內存分布就變成了下面這個樣子:

2: 內存分區結構

  1. 代碼區
  2. 數據區
    1. 靜態存儲區
      1. 全局變量區
      2. 靜態變量區
      3. 常量區(靜態常量區)
        1. 字符串常量
        2. 常變量區

  • 可執行二進制程序 = 代碼段(text)+數據段(data)+BSS段
    • 而當程序被加載到內存單元時,則需要另外兩個域:堆域和棧域。
    • 一個正在運行的C程序占用的內存區域分為代碼段、初始化數據段、未初始化數據段(BSS)、堆、棧5個部分。

  • 正在運行的C程序 = 代碼段(text)+初始化數據段(data)+未初始化數據段(BSS)+堆(heap)+棧(stack)
    • 在將應用程序加載到內存空間執行時,操作系統負責代碼段、數據段和BSS段的加載,并將在內存中為這些段分配空間。
    • 棧亦由操作系統分配和管理,而不需要程序員顯示地管理;
    • 堆段由程序員自己管理,即顯示地申請和釋放空間。

  • 動態分配與靜態分配,二者最大的區別在于:
    • 直到Run-Time(運行)的時候,執行動態分配
    • 而在compile-time(編譯)的時候,就已經決定好了分配多少Text+Data+BSS+Stack。
    • 通過malloc()動態分配的內存,需要程序員手工調用free()釋放內存,否則容易導致內存泄露,
    • 而靜態分配的內存則在進程執行結束后系統釋放(Text, Data), 但Stack段中的數據很短暫,函數退出立即被銷毀。

進程和線程內存

我們都知道進程運行時,會有一個棧空間(stack)和一個堆空間(heap), 棧空間用于函數調用和局部變量,堆空間是C語言的 malloc 來分配的全局指針。

這些都是進程的私有數據,除了這些,還有映射進來的動態庫,進程間的共享內存等共享空間。另外,操作系統還支持預留虛擬地址空間的功能(延遲分配),也就是在讀寫該內存的時候,操作系統才進行物理內存的分配,因此進程占用的空間情況還是比較復雜的。下面簡單地說明一下。

  1. VSZ:Virtual Memory Size(虛擬內存大小)。進程占用的全部地址空間,共享庫,預分配內存,交換分區等都包含在里面。因此,它遠遠大于實際的占用的內存空間。
  2. RSS:Resident Set Size(駐留集大小), 實際占用的物理內存,它包含共享庫,但不包含在交換分區的空間。隨著程序的運行,RSS也會跟著增長,VSZ將是它的上限。
  3. PSS:Proportional Set Size, 也是實際分配的物理內存,與RSS的區別是,它以平分的方式來計算共享庫的大小(共享庫 / 進程個數), RSS會把共享庫的大小全部計算進來。
  4. USS:Unique Set Size, 進程的私有內存(獨自使用的庫,堆等空間),不包含共享的內存空間。
  5. ANON: Anonymous memory,匿名內存 —— 沒有文件關聯的內存頁面。Linux會自動映射文件到內存,讀取的文件后,會自動緩存到內存。如果,應用程序只是使用mmap(MAP_ANONYMOUS) 分配一些內存頁面沒有文件關聯,就稱為“匿名內存”。
  6. Dirty: dirty pages , 臟頁大小 —— 還沒有寫回到硬盤的緩存頁面。
  7. VIRT: 同VSZ。
  8. RES: 同RSS。

內存指標

Item

全稱

含義

等價

USS

Unique Set Size

物理內存

進程獨占的內存

PSS

Proportional Set Size

物理內存

Pss =Uss+按比例包含共享庫

RSS

Resient Set Size

物理內存

RSS=USS+包含共享庫

VSS

Virtual Set Size

虛擬內存

VSS = RSS+未分配實際物理內存

內存的大小關系:VSS>RSS>=PSS>=USS

在實際分析中,一般是以PSS的內存為準,且也是最符合實際情況的統計值

假如進程A(2k),只依賴動態庫B(1000k) ;A 分配 128k的匿名空間,200k的堆棧和堆的空間——實際使用100k。其中動態庫B被 2個進程共享,實際加載200k,那么 ——

VSZ = 2k + 1000k + 128k + 200k = 1230k

RSS = 2k + 200k + 128k + 100k = 430k

PSS = 2k + 200k / 2 + 128k + 100k = 330k

USS = 2k + 128k + 100k = 230k

ANON = 128k

區別

VSS : Virtual Set Size 虛擬耗用內存(包含共享庫占用的內存),即單個進程全部可訪問的地址空間,其大小可能包括還尚未在內存中駐留的部分。對于確定單個進程實際內存使用大小,VSS用處不大。

RSS : Resident Set Size 實際使用物理內存(包含共享庫占用的內存),即單個進程實際占用的內存大小,RSS不太準確的地方在于它包括該進程所使用共享庫全部內存大小。對于一個共享庫,可能被多個進程使用,實際該共享庫只會被裝入內存一次。

PSS : Proportional Set Size 實際使用的物理內存(比例分配共享庫占用的內存)PSS相對于RSS計算共享庫內存大小是按比例的。N個進程共享,該庫對PSS大小的貢獻只有1/N。

USS : Unique Set Size 進程獨自占用的物理內存(不包含共享庫占用的內存)即單個進程私有的內存大小,即該進程獨占的內存部分。USS揭示了運行一個特定進程在的真實內存增量大小。如果進程終止,USS就是實際被返還給系統的內存大小。

    PS:下一篇介紹:進程內存分布--之單線程和多線程編寫代碼來內存分布呈現memory-layout.cpp?

    關注我,后續還有更多專題博文分享,謝謝!!!??

    本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
    如若轉載,請注明出處:http://www.pswp.cn/bicheng/75866.shtml
    繁體地址,請注明出處:http://hk.pswp.cn/bicheng/75866.shtml
    英文地址,請注明出處:http://en.pswp.cn/bicheng/75866.shtml

    如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

    相關文章

    WEB安全--內網滲透--LMNTLM基礎

    一、前言 LM Hash和NTLM Hash是Windows系統中的兩種加密算法,不過LM Hash加密算法存在缺陷,在Windows Vista 和 Windows Server 2008開始,默認情況下只存儲NTLM Hash,LM Hash將不再存在。所以我們會著重分析NTLM Hash。 在我們內…

    時尚優雅奢華品牌包裝徽標設計襯線英文字體安裝包 Kagea – Luxury Women Ligature Font

    Kagea 是一種復雜的襯線字體,有常規和壓縮兩種樣式,具有 50 連字和替代字體,并支持多種語言。其精致的比例和別致的字體使其成為高端品牌、編輯布局、高檔包裝、時尚品牌和奢侈品設計的理想選擇。 包含內容: TTF、OTF 和 WOFF 格…

    cut命令用法

    cut 是 Linux/Unix 系統中一個用于按列提取文本內容的命令,常用于處理結構化文本(如 CSV、日志、配置文件等)。它通過分隔符、字符位置或字節位置來切割文本,提取指定部分。 核心功能 按字段(列)提取&#…

    美國mlb與韓國mlb的關系·棒球9號位

    MLB(Major League Baseball,美國職業棒球大聯盟)作為全球最高水平的職業棒球聯賽,與韓國市場流行的“MLB”時尚品牌之間存在著授權合作關系,但兩者在業務范疇和品牌定位上存在顯著差異。 一、品牌授權背景:…

    從吉卜力漫畫到藝術創造:GPT-4o多種風格繪圖Prompt大全

    在3月底,GPT-4o掀起了一陣吉卜力繪圖浪潮,大家紛紛輸入一張圖片,讓4o模型進行風格化遷移,其中吉卜力風格的漫畫在社交媒體上最為火熱。在大家爭議4o的訓練數據是否侵權和4o背后的技術原理的時候,我們先來玩一玩&#x…

    Leetcode 3510. Minimum Pair Removal to Sort Array II

    Leetcode 3510. Minimum Pair Removal to Sort Array II 1. 解題思路2. 代碼實現 題目鏈接:3510. Minimum Pair Removal to Sort Array II 1. 解題思路 這一題和題目3507. Minimum Pair Removal to Sort Array I本質上是同一道題目,唯一的區別在于時間…

    【數學建模】(時間序列模型)ARIMA時間序列模型

    ARIMA時間序列模型詳解及常見時間序列模型概覽 文章目錄 ARIMA時間序列模型詳解及常見時間序列模型概覽1 引言2 ARIMA模型的基本概念3 ARIMA模型的組成部分詳解3.1 AR模型 (自回歸模型)3.2 MA模型 (移動平均模型)3 I (差分) 4 ARIMA模型的建模步驟5 Python實現ARIMA模型6 常見時…

    嵌入式AI開發者職業成長路線圖

    嵌入式AI開發者職業成長路線圖 一、核心技術能力構建 1. 深度學習框架 TensorFlow/TensorFlow Lite:適合部署到嵌入式設備PyTorch:研究和原型開發ONNX:模型轉換與部署 2. 模型理解與應用 卷積神經網絡(CNN):圖像識別、目標檢…

    單元測試之mockito

    簡介 mockito是一款模擬測試框架,用于Java開發中的單元測試。通過mockito,可以創建和配置一個對象,通過它來替換對象的外部依賴。 作用:模擬一個類的外部依賴,保證單元測試的獨立性。例如,在類A中會調用類…

    Oracle數據庫數據編程SQL<5 正則表達式函數*****>

    Oracle 提供了一組強大的正則表達式函數,用于在 SQL 和 PL/SQL 中進行復雜的模式匹配和文本處理。這些函數基于 POSIX 標準正則表達式,功能強大且靈活。 目錄 一、Oracle 正則表達式函數概覽 二、函數詳解及示例 1. REGEXP_LIKE 2. REGEXP_INSTR 3. REGEXP_SUBSTR 4. …

    el-tabs添加按鈕增加點擊禁止樣式

    前置文章 一、vue使用element-ui自定義樣式思路分享【實操】 二、vue3&ts&el-tabs多個tab表單校驗 現狀確認 點擊添加按鈕,沒有點擊樣式,用戶感知不明顯沒有限制最大的tab添加數量,可以無限添加 調整目標&代碼編寫 調整目標…

    DB-Mysql中TIMESTAMP與DATETIME的區別

    文章目錄 ?存儲范圍??時區處理?存儲空間?默認值和自動更新??零值處理?適用場景?總結 在MySQL中,TIMESTAMP和DATETIME是兩種常用的日期時間數據類型,它們雖然都用于存儲日期和時間,但在多個方面存在顯著差異。以下是它們的主要區別&a…

    Spring 中有哪些設計模式?

    🧠 一、Spring 中常見的設計模式 設計模式類型Spring 中的應用場景單例模式創建型默認 Bean 是單例的工廠模式創建型BeanFactory、FactoryBean抽象工廠模式創建型ApplicationContext 提供多個工廠接口代理模式結構型AOP 動態代理(JDK/CGLIB)…

    C# Winform 入門(3)之尺寸同比例縮放

    放大前 放大后 1.定義當前窗體的寬度和高度 private float x;//定義當前窗體的寬度private float y;//定義當前窗臺的高度 2.接收當前窗體的尺寸大小 x this.Width;//存儲原始寬度ythis.Height;//存儲原始高度setTag(this);//為控件設置 Tag 屬性 3.聲明方法,獲…

    從零開始的編程-java篇1.6.3

    前言: 通過實踐而發現真理,又通過實踐而證實真理和發展真理。從感性認識而能動地發展到理性認識,又從理性認識而能動地指導革命實踐,改造主觀世界和客觀世界。實踐、認識、再實踐、再認識,這種形式,循環往…

    【Redis】數據的淘汰策略

    目錄 淘汰策略方案(8種) LRU和LFU策略的區別 使用建議 手搓LRU算法 方式一 方式二 大家好,我是jstart千語。今天和大家回來聊一下redis,這次要講的是它的淘汰策略。為什么需要淘汰策略呢,就是當redis里面的內存占…

    【前端】Node.js一本通

    近兩天更新完畢,建議關注收藏點贊。 目錄 復習Node.js概述使用fs文件系統模塊path路徑模塊 http模塊 復習 為什么JS可以在瀏覽器中執行 原理:待執行的JS代碼->JS解析引擎 不同的瀏覽器使用不同的 JavaScript 解析引擎:其中,C…

    【AI論文】JavisDiT: 具備層次化時空先驗同步機制的聯合音視頻擴散Transformer

    摘要:本文介紹了一種新型的聯合音頻-視頻擴散變換器JavisDiT,該變換器專為同步音頻-視頻生成(JAVG)而設計。 基于強大的擴散變換器(DiT)架構,JavisDiT能夠根據開放式用戶提示同時生成高質量的音…

    Java-實現公有字段自動注入(創建人、創建時間、修改人、修改時間)

    文章目錄 Mybatis-plus實現自動注入定義 MetaObjectHandler配置 MyBatis-Plus 使用 MetaObjectHandler實體類字段注解使用服務類進行操作測試 Jpa啟用審計功能實現自動注入添加依賴啟動類啟用審計功能實現AuditorAware接口實體類中使用審計注解 總結 自動注入創建人、創建時間、…

    金融機構開源軟件風險管理體系建設

    開源軟件為金融行業帶來了創新活力的同時,也引入了一系列獨特的風險。金融機構需要構建系統化的風險管理體系,以識別和應對開源軟件在全生命周期中的各種風險點。下面我們將解析開源軟件在金融場景下的主要風險類別,并探討如何建立健全的風險…