進程虛擬地址空間

1. 程序地址空間回顧

我們在學習語言層面時,會了解到這樣的空間布局圖,我們先對他進行分區了解:

如果以靜態static修飾的變量就會當成已初始化全局變量來看待,存放在已初始化數據區和未初始化數據區之前。

如果不用static修飾test的話,test只是?

?


2.一個例子引入虛擬地址

輸出出來的變量值和地址是?模?樣的,很好理解呀,因為?進程按照?進程為模版

變量值不一樣可以理解,進程之前是具有獨立性的,即便是父子進程。

但是??進程輸出地址是?致的,但是變量內容不?樣的 why ???

但是為什么輸出地址一模一樣卻有兩個不同的值呢?

??進程,輸出地址是?致的,但是變量內容不?樣!能得出如下結論:

變量內容不?樣,所以??進程輸出的變量絕對不是同?個變量
但地址值是?樣的,說明,該地址絕對 不是物理地址!
在Linux地址下,這種地址叫做 虛擬地址
我們在?C/C++語?所看到的地址, 全部都是虛擬地址 !物理地址, 用戶?概看不到,由OS統?
管理
OS必須負責將 虛擬地址 轉化成 物理地址

3.進程地址空間

所以之前說‘程序的地址空間’是不準確的,準確的應該說成 進程地址空間 ,那該如何理解呢?看
圖:
分?&虛擬地址空間

?

注:上?的圖就?矣說明問題,同?個變量,地址相同,其實是虛擬地址相同,內容不同其實是被映射到了不同的物理地址!

虛擬地址空間,本質一定是一個內核數據結構!

空間區域劃分:本質其實只要有線性空間的一段開始地址和結束地址表明一段范圍即可。

區域劃分:表明開始地址和結束地址,區域內部的內容都屬于我

4. 虛擬內存管理
?

描述linux下進程的地址空間的所有的信息的結構體是 mm_struct (內存描述符)。每個進程只有?個mm_struct結構,(操作系統給畫的餅)在每個進程的task_struct結構中,有?個指針指向該進程的mm_struct結構體指針?。

struct task_struct
{/*...*/struct mm_struct *mm;//對于普通的??進程來說該字段指向他的虛擬地址空間的??空間部分,對于內核線程來說這部分為NULL。struct mm_struct *active_mm; // 該字段是內核線程使?的。當該進程是內核線程時,它的mm字段為NULL,表?沒有內存地址空間,可也并          不是真正的沒有,這是因為所有進程關于內核的映射都是?樣的,內核線程可以使?任意進程的地址空間。/*...*/
}    

可以說,mm_struct結構是對整個??空間的描述。每?個進程都會有??獨?的mm_struct,(把每一個進程映射到不同的物理內存處)這樣每?個進程都會有??獨?的地址空間才能互不?擾。先來看看由task_struct到mm_struct,進程的地址空間的分布情況:

定位mm_struct?件所在位置和task_struct所在路徑是?樣的,不過他們所在?件是不?樣的, mm_struct所在的?件是mm_types.h。
?

struct mm_struct
{struct vm_area_struct *mmap; /* 指向虛擬區間(VMA)鏈表 */struct rb_root mm_rb; /* red_black樹 */unsigned long task_size; /*具有該結構體的進程的虛擬地址空間的??*///...// 代碼段、數據段、堆棧段、參數段及環境段的起始和結束地址。unsigned long start_code, end_code, start_data, end_data;unsigned long start_brk, brk, start_stack;unsigned long arg_start, arg_end, env_start, env_end;//...}

那既然每?個進程都會有??獨?的mm_struct,操作系統肯定是要將這么多進程的mm_struct組織起來的!虛擬空間的組織?式有兩種:


1. 當虛擬區較少時采取單鏈表,由mmap指針指向這個鏈表;

2. 當虛擬區間多時采取紅?樹進?管理,由mm_rb指向這棵樹。

linux內核使? vm_area_struct 結構來表??個獨?的虛擬內存區域(VMA),由于每個不同質的虛擬內存區域功能和內部機制都不同,因此?個進程使?多個vm_area_struct結構來分別表?不同類型的虛擬內存區域。上?提到的兩種組織?式使?的就是vm_area_struct結構來連接各個VMA,?便進程快速訪問。

struct vm_area_struct {unsigned long vm_start; //虛存區起始
unsigned long vm_end; //虛存區結束
struct vm_area_struct *vm_next, *vm_prev; //前后指針
struct rb_node vm_rb; //紅?樹中的位置
unsigned long rb_subtree_gap;
struct mm_struct *vm_mm; //所屬的 mm_struct
pgprot_t vm_page_prot;
unsigned long vm_flags; //標志位
struct {
struct rb_node rb;
unsigned long rb_subtree_last;
} shared;
struct list_head anon_vma_chain;
struct anon_vma *anon_vma;
const struct vm_operations_struct *vm_ops; //vma對應的實際操作
unsigned long vm_pgoff; //?件映射偏移量
struct file * vm_file; //映射的?件
void * vm_private_data; //私有數據
atomic_long_t swap_readahead_info;
#ifndef CONFIG_MMU
struct vm_region *vm_region; /* NOMMU mapping region */
#endif
#ifdef CONFIG_NUMA
struct mempolicy *vm_policy; /* NUMA policy for the VMA */
#endif
struct vm_userfaultfd_ctx vm_userfaultfd_ctx;
} __randomize_layout;

所以我們可以對上圖在進?更細致的描述,如下圖所?:

?

5. 為什么要有虛擬地址空間

這個問題其實可以轉化為:如果程序直接可以操作物理內存會造成什么問題?

在早期的計算機中,要運??個程序,會把這些程序全都裝?內存,程序都是直接運?在內存上的,也就是說程序中訪問的內存地址都是實際的物理內存地址。當計算機同時運?多個程序時,必須保證這些程序?到的內存總量要?于計算機實際物理內存的??。

那當程序同時運?多個程序時,操作系統是如何為這些程序分配內存的呢?例如某臺計算機總的內存??是128M,現在同時運?兩個程序A和B,A需占?內存10M,B需占?內存110。計算機在給程序分配內存時會采取這樣的?法:先將內存中的前10M分配給程序A,接著再從內存中剩余的118M中劃分出110M分配給程序B。

這種分配?法可以保證程序A和程序B都能運?,但是這種簡單的內存分配策略問題很多。

  • ?安全?險

每個進程都可以訪問任意的內存空間,這也就意味著任意?個進程都能夠去讀寫系統相關內存區域,如果是?個??病毒,那么他就能隨意的修改內存空間,讓設備直接癱瘓。

  • 地址不確定

眾所周知,編譯完成后的程序是存放在硬盤上的,當運?的時候,需要將程序搬到內存當中去運?,如果直接使?物理地址的話,我們?法確定內存現在使?到哪?了,也就是說拷?的實際內存地址每?次運?都是不確定的,?如:第?次執?a.out時候,內存當中?個進程都沒有運?,所以搬移到內存地址是0x00000000,但是第?次的時候,內存已經有10個進程在運?了,那執?a.out的時候,內存地址就不?定了

  • ?效率低下

?如果直接使?物理內存的話,?個進程就是作為?個整體(內存塊)操作的,如果出現物理內存不夠?的時候,我們?般的辦法是將不常?的進程拷?到磁盤的交換分區中,好騰出內存,但是如果是物理地址的話,就需要將整個進程?起拷?,這樣,在內存和磁盤之間拷?時間太?,效率較低。

存在這么多問題,有了虛擬地址空間和分?機制就能解決了嗎?當然!

  • 地址空間和?表是OS創建并維護的!是不是也就意味著,凡是想使?地址空間和?表進?映射,也?定要在OS的監管之下來進?訪問!!也順便保護了物理內存中的所有的合法數據 ,包括各個進程以及內核的相關有效數據!
  • 因為有地址空間的存在和?表的映射的存在,我們的物理內存中可以對未來的數據進?任意位置的加載!物理內存的分配 和 進程的管理就可以做到沒有關系,進程管理模塊和內存管理模塊就完成了解耦合

因為有地址空間的存在,所以我們在C、C++語?上new, malloc空間的時候,其實是在地址空間上申請的,物理內存可以甚??個字節都不給你。?當你真正進?對物理地址空間訪問的時候,才執?內存的相關管理算法,幫你申請內存,構建?表映射關系(延遲分配),這是由操作系統?動完成,??包括進程完全0感知!!

  • 因為?表的映射的存在,程序在物理內存中理論上就可以任意位置加載。它可以將地址空間上的虛擬地址和物理地址進?映射,在進程視?所有的內存分布都可以是有序的。

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

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

相關文章

C語言學習day17-----位運算

目錄 1.位運算 1.1基礎知識 1.1.1定義 1.1.2用途 1.1.3軟件控制硬件 1.2運算符 1.2.1與 & 1.2.2或 | 1.2.3非 ~ 1.2.4異或 ^ 1.2.5左移 << 1.2.6右移 >> 1.2.7代碼實現 1.2.8置0 1.2.9置1 1.2.10不借助第三方變量&#xff0c;實現兩個數的交換…

【linux】簡單的shell腳本練習

簡單易學 解釋性語言&#xff0c;不需要編譯即可執行 對于一個合格的系統管理員來說&#xff0c;學習和掌握Shell編程是非常重要的&#xff0c;通過shell程序&#xff0c;可以在很大程度上簡化日常的維護工作&#xff0c;使得管理員從簡單的重復勞動中解脫出來 用戶輸入任意兩…

機構運動分析系統開發(Python實現)

機構運動分析系統開發(Python實現) 一、引言 機構運動分析是機械工程的核心內容,涉及位置、速度和加速度分析。本系統基于Python開發,實現了平面連桿機構的完整運動學分析,包含數學建模、數值計算和可視化功能。 二、系統架構設計 #mermaid-svg-bT8TPKQ98UU9ERet {font…

工程師生活:清除電熱水壺(鍋)水垢方法

清除電熱水壺&#xff08;鍋&#xff09;水垢方法 水垢是水加熱時自然形成的鈣質沉淀物&#xff0c;常粘附在水壺內壁及發熱盤上。它不僅影響水的品質&#xff0c;還會縮短水壺的使用壽命&#xff0c;因此需要定期清除。建議根據各地水質不同&#xff0c;每年除垢 2 至 4 次。…

[分布式并行策略] 數據并行 DP/DDP/FSDP/ZeRO

上篇文章【[論文品鑒] DeepSeek V3 最新論文 之 DeepEP】 介紹了分布式并行策略中的EP&#xff0c;簡單的提到了其他幾種并行策略&#xff0c;但礙于精力和篇幅限制決定將內容分幾期&#xff0c;本期首先介紹DP&#xff0c;但并不是因為DP簡單&#xff0c;相反DP的水也很深&…

LeeCode144二叉樹的前序遍歷

項目場景&#xff1a; 給你二叉樹的根節點 root &#xff0c;返回它節點值的 前序 遍歷。 示例 1&#xff1a; 輸入&#xff1a;root [1,null,2,3] 輸出&#xff1a;[1,2,3] 解釋&#xff1a; 示例 2&#xff1a; 輸入&#xff1a;root [1,2,3,4,5,null,8,null,null,6,7…

日本生活:日語語言學校-日語作文-溝通無國界(3)-題目:わたしの友達

日本生活&#xff1a;日語語言學校-日語作文-溝通無國界&#xff08;&#xff13;&#xff09;-題目&#xff1a;わたしの友達 1-前言2-作文原稿3-作文日語和譯本&#xff08;1&#xff09;日文原文&#xff08;2&#xff09;對應中文&#xff08;3&#xff09;對應英文 4-老師…

使用 rsync 拉取文件(從遠程服務器同步到本地)

最近在做服務器遷移&#xff0c;文件好幾個T。。。。只能單向訪問&#xff0c;服務器。怎么辦&#xff01;&#xff01;&#xff01; 之前一直是使用rsync 服務器和服務器之間的雙向同步、備份&#xff08;這是推的&#xff09;。現在服務器要遷移&#xff0c;只能單向訪問&am…

Linux 并發編程:從線程池到單例模式的深度實踐

文章目錄 一、普通線程池&#xff1a;高效線程管理的核心方案1. 線程池概念&#xff1a;為什么需要 "線程工廠"&#xff1f;2. 線程池的實現&#xff1a;從 0 到 1 構建基礎框架 二、模式封裝&#xff1a;跨語言線程庫實現1. C 模板化實現&#xff1a;類型安全的泛型…

2013年SEVC SCI2區,自適應變領域搜索算法Adaptive VNS+多目標設施布局,深度解析+性能實測

目錄 1.摘要2.自適應局部搜索原理3.自適應變領域搜索算法Adaptive VNS4.結果展示5.參考文獻6.代碼獲取7.算法輔導應用定制讀者交流 1.摘要 VNS是一種探索性的局部搜索方法&#xff0c;其基本思想是在局部搜索過程中系統性地更換鄰域。傳統局部搜索應用于進化算法每一代的解上&…

詳細介紹醫學影像顯示中窗位和窗寬

在醫學影像&#xff08;如DICOM格式的CT圖像&#xff09;中&#xff0c;**窗寬&#xff08;Window Width, WW&#xff09;和窗位&#xff08;Window Level, WL&#xff09;**是兩個核心參數&#xff0c;用于調整圖像的顯示對比度和亮度&#xff0c;從而優化不同組織的可視化效果…

Unity_VR_如何用鍵鼠模擬VR輸入

文章目錄 [TOC] 一、創建項目1.直接創建VR核心模板&#xff08;簡單&#xff09;2.創建3D核心模板導入XR包 二、添加XR設備模擬器1.打開包管理器2.添加XR設備模擬器3.將XR設備模擬器拖到場景中4.運行即可用鍵盤模擬VR輸入 一、創建項目 1.直接創建VR核心模板&#xff08;簡單&…

SpringBoot定時監控數據庫狀態

1.application.properties配置文件 # config for mysql spring.datasource.url jdbc\:mysql\://127.0.0.1\:3306/數據庫名?characterEncoding\utf8&useSSL\false spring.datasource.username 賬號 spring.datasource.password 密碼 spring.datasource.validation-quer…

Qt聯合Halcon開發一:Qt配置Halcon環境【詳細圖解流程】

在Qt中使用Halcon庫進行圖像處理開發&#xff0c;可以有效地結合Qt的圖形界面和Halcon強大的計算機視覺功能。下面是詳細的配置過程&#xff0c;幫助你在Qt項目中成功集成Halcon庫。 步驟 1: 安裝Halcon軟件并授權 首先&#xff0c;確保你已經在電腦上安裝了Halcon軟件&#x…

一體化(HIS系統)醫院信息系統,讓醫療數據互聯互通

在醫療信息化浪潮下&#xff0c;HIS系統、LIS系統、PACS系統、電子病歷系統等信息系統成為醫療機構必不可少的一部分&#xff0c;從患者掛號到看診&#xff0c;從各種檢查到用藥&#xff0c;從院內治療到院外管理……醫療機構不同部門、不同科室的各類醫療、管理業務幾乎都初步…

Spring Boot 的 3 種二級緩存落地方式

在高并發系統設計中&#xff0c;緩存是提升性能的關鍵策略之一。隨著業務的發展&#xff0c;單一的緩存方案往往無法同時兼顧性能、可靠性和一致性等多方面需求。 此時&#xff0c;二級緩存架構應運而生&#xff0c;本文將介紹在Spring Boot中實現二級緩存的三種方案。 一、二…

Android Studio Profiler使用

一:memory 參考文獻: AndroidStudio之內層泄漏工具Profiler使用指南_android studio profiler-CSDN博客

Zephyr boot

<!DOCTYPE html> <html lang"zh-CN"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <title>Zephyr設備初始化機制交互式解析…

騰訊地圖Web版解決熱力圖被輪廓覆蓋的問題

前言 你好&#xff0c;我是喵喵俠。 還記得那天傍晚&#xff0c;我正對著電腦調試一個騰訊地圖的熱力圖頁面。項目是一個區域人流密度可視化模塊&#xff0c;我加了一個淡藍色的輪廓圖層用于表示區域范圍&#xff0c;熱力圖放在下面用于展示人流熱度。效果一預覽&#xff0c;…

【JVMGC垃圾回收場景總結】

文章目錄 CMS在并發標記階段&#xff0c;已經被標記的對象&#xff0c;又被新生代跨帶引用&#xff0c;這時JVM會怎么處理?為什么 Minor GC 會發生 STW&#xff1f;有哪些對象是在棧上分配的&#xff1f;對象在 JVM 中的內存結構為什么需要對齊填充&#xff1f;JVM 對象分配空…