• <output id="aynwq"><form id="aynwq"><code id="aynwq"></code></form></output>

    <mark id="aynwq"><option id="aynwq"></option></mark>
  • <mark id="aynwq"><option id="aynwq"></option></mark><label id="aynwq"><dl id="aynwq"></dl></label>
  • 學習啦 > 學習電腦 > 網絡知識 > 網絡基礎知識 > 物理虛擬內存

    物理虛擬內存

    時間: 春健736 分享

    物理虛擬內存

      有網友問到小編物理虛擬內存是什么,那么物理虛擬內存到底是什么呢?學習啦小編為大家介紹下。供大家參考!

      物理虛擬內存

      前一段時間在面試總監的時候,總監問了我這樣的一個問題:你跟我說說物理內存和虛擬內存到底是怎么一回事?

      其實之前我看過這個問題,據我理解的,當時是這么回答的“進程在運行的時候,操作系統都為其分配一個4GB的地址空間,即所謂的虛擬地址空間,一般情況下,當我們的程序很大的時候,實際的物理內存根本不能滿足我們的需求的時候,這個時候操作系統就會借助磁盤空間來做虛擬的內存空間,把當前進程不需要的數據放在磁盤上,等到用到的時候,在利用調度算法把所需要的數據從磁盤空間上調度到內存,虛擬內存就是為了擴大內存的容量,每當我們要運行一個程序的時候經過編譯以后形成的僅僅是邏輯上的空間,根本不是可以直接運行的內存空間,所以它還存在一個地址映射的概念。”當時感覺回答的很是籠統,只見總監在最后說了一句,你下去還是把這一塊的內容在好好看看,所以今天就好好的把這個概念理一理。

      首先我從最基本的概念說起,什么是物理內存的概念,虛擬內存的概念?

      物理內存,在應用中,自然是顧名思義,物理上,真實的插在板子上的內存是多大就是多大了。而在CPU中的概念,物理內存就是CPU的地址線可以直接進行尋址的內存空間大小。比如8086只有20根地址線,那么它的尋址空間就是1MB,我們就說8086能支持1MB的物理內存,及時我們安裝了128M的內存條在板子上,我們也只能說8086擁有1MB的物理內存空間。同理我們現在大部分使用的是32位的機子,32位的386以上CPU就可以支持最大4GB的物理內存空間了。

      先說說為什么會有虛擬內存和物理內存的區別。正在運行的一個進程,他所需的內存是有可能大于內存條容量之和的,比如你的內存條是256M,你的程序卻要創建一個2G的數據區,那么不是所有數據都能一起加載到內存(物理內存)中,勢必有一部分數據要放到其他介質中(比如硬盤),待進程需要訪問那部分數據時,在通過調度進入物理內存。所以,虛擬內存是進程運行時所有內存空間的總和,并且可能有一部分不在物理內存中,而物理內存就是我們平時所了解的內存條。有的地方呢,也叫這個虛擬內存為內存交換區。關鍵的是不要把虛擬內存跟真實的插在主板上的內存條相掛鉤,虛擬內存它是“虛擬的”不存在,假的啦,它只是內存管理的一種抽象!

      那么,什么是虛擬內存地址和物理內存地址呢。假設你的計算機是32位,那么它的地址總線是32位的,也就是它可以尋址0~0xFFFFFFFF(4G)的地址空間,但如果你的計算機只有256M的物理內存0x~0x0FFFFFFF(256M),同時你的進程產生了一個不在這256M地址空間中的地址,那么計算機該如何處理呢?回答這個問題前,先說明計算機的內存分頁機制。

      計算機會對虛擬內存地址空間(32位為4G)分頁產生頁(page),對物理內存地址空間(假設256M)分頁產生頁幀(page frame),這個頁和頁幀的大小是一樣大的,所以呢,在這里,虛擬內存頁的個數勢必要大于物理內存頁幀的個數。在計算機上有一個頁表(page table),就是映射虛擬內存頁到物理內存頁的,更確切的說是頁號到頁幀號的映射,而且是一對一的映射。但是問題來了,虛擬內存頁的個數 > 物理內存頁幀的個數,豈不是有些虛擬內存頁的地址永遠沒有對應的物理內存地址空間?不是的,操作系統是這樣處理的。操作系統有個頁面失效(page fault)功能。操作系統找到一個最少使用的頁幀,讓他失效,并把它寫入磁盤,隨后把需要訪問的頁放到頁幀中,并修改頁表中的映射,這樣就保證所有的頁都有被調度的可能了。這就是處理虛擬內存地址到物理內存的步驟。

      現在來回答什么是虛擬內存地址和物理內存地址。虛擬內存地址由頁號(與頁表中的頁號關聯)和偏移量組成。頁號就不必解釋了,上面已經說了,頁號對應的映射到一個頁幀。那么,說說偏移量。偏移量就是我上面說的頁(或者頁幀)的大小,即這個頁(或者頁幀)到底能存多少數據。舉個例子,有一個虛擬地址它的頁號是4,偏移量是20,那么他的尋址過程是這樣的:首先到頁表中找到頁號4對應的頁幀號(比如為8),如果頁不在內存中,則用失效機制調入頁,否則把頁幀號和偏移量傳給MMU(CPU的內存管理單元)組成一個物理上真正存在的地址,接著就是訪問物理內存中的數據了。總結起來說,虛擬內存地址的大小是與地址總線位數相關,物理內存地址的大小跟物理內存條的容量相關。

      第一層理解

      1. 每個進程都有自己獨立的4G內存空間,各個進程的內存空間具有類似的結構

      2. 一個新進程建立的時候,將會建立起自己的內存空間,此進程的數據,代碼等從磁盤拷貝到自己的進程空間,哪些數據在哪里,都由進程控制表中的task_struct記錄,task_struct中記錄中一條鏈表,記錄中內存空間的分配情況,哪些地址有數據,哪些地址無數據,哪些可讀,哪些可寫,都可以通過這個鏈表記錄

      3. 每個進程已經分配的內存空間,都與對應的磁盤空間映射

      問題:

      計算機明明沒有那么多內存(n個進程的話就需要n*4G)內存

      建立一個進程,就要把磁盤上的程序文件拷貝到進程對應的內存中去,對于一個程序對應的多個進程這種情況,浪費內存!

      第二層理解

      1. 每個進程的4G內存空間只是虛擬內存空間,每次訪問內存空間的某個地址,都需要把地址翻譯為實際物理內存地址

      2. 所有進程共享同一物理內存,每個進程只把自己目前需要的虛擬內存空間映射并存儲到物理內存上。

      3. 進程要知道哪些內存地址上的數據在物理內存上,哪些不在,還有在物理內存上的哪里,需要用頁表來記錄

      4. 頁表的每一個表項分兩部分,第一部分記錄此頁是否在物理內存上,第二部分記錄物理內存頁的地址(如果在的話)

      5. 當進程訪問某個虛擬地址,去看頁表,如果發現對應的數據不在物理內存中,則缺頁異常

      6. 缺頁異常的處理過程,就是把進程需要的數據從磁盤上拷貝到物理內存中,如果內存已經滿了,沒有空地方了,那就找一個頁覆蓋,當然如果被覆蓋的頁曾經被修改過,需要將此頁寫回磁盤

      總結:

      優點:

      1.既然每個進程的內存空間都是一致而且固定的,所以鏈接器在鏈接可執行文件時,可以設定內存地址,而不用去管這些數據最終實際的內存地址,這是有獨立內存空間的好處

      2.當不同的進程使用同樣的代碼時,比如庫文件中的代碼,物理內存中可以只存儲一份這樣的代碼,不同的進程只需要把自己的虛擬內存映射過去就可以了,節省內存

      3.在程序需要分配連續的內存空間的時候,只需要在虛擬內存空間分配連續空間,而不需要實際物理內存的連續空間,可以利用碎片。

      另外,事實上,在每個進程創建加載時,內核只是為進程“創建”了虛擬內存的布局,具體就是初始化進程控制表中內存相關的鏈表,實際上并不立即就把虛擬內存對應位置的程序數據和代碼(比如.text .data段)拷貝到物理內存中,只是建立好虛擬內存和磁盤文件之間的映射就好(叫做存儲器映射),等到運行到對應的程序時,才會通過缺頁異常,來拷貝數據。還有進程運行過程中,要動態分配內存,比如malloc時,也只是分配了虛擬內存,即為這塊虛擬內存對應的頁表項做相應設置,當進程真正訪問到此數據時,才引發缺頁異常。

      補充理解:

      虛擬存儲器涉及三個概念: 虛擬存儲空間,磁盤空間,內存空間

      可以認為虛擬空間都被映射到了磁盤空間中,(事實上也是按需要映射到磁盤空間上,通過mmap),并且由頁表記錄映射位置,當訪問到某個地址的時候,通過頁表中的有效位,可以得知此數據是否在內存中,如果不是,則通過缺頁異常,將磁盤對應的數據拷貝到內存中,如果沒有空閑內存,則選擇犧牲頁面,替換其他頁面。

      mmap是用來建立從虛擬空間到磁盤空間的映射的,可以將一個虛擬空間地址映射到一個磁盤文件上,當不設置這個地址時,則由系統自動設置,函數返回對應的內存地址(虛擬地址),當訪問這個地址的時候,就需要把磁盤上的內容拷貝到內存了,然后就可以讀或者寫,最后通過manmap可以將內存上的數據換回到磁盤,也就是解除虛擬空間和內存空間的映射,這也是一種讀寫磁盤文件的方法,也是一種進程共享數據的方法 共享內存

    接下來我們來討論下物理內存:

      在內核態申請內存比在用戶態申請內存要更為直接,它沒有采用用戶態那種延遲分配內存技術。內核認為一旦有內核函數申請內存,那么就必須立刻滿足該申請內存的請求,并且這個請求一定是正確合理的。相反,對于用戶態申請內存的請求,內核總是盡量延后分配物理內存,用戶進程總是先獲得一個虛擬內存區的使用權,最終通過缺頁異常獲得一塊真正的物理內存。

      1.物理內存的內核映射

      IA32架構中內核虛擬地址空間只有1GB大小(從3GB到4GB),因此可以直接將1GB大小的物理內存(即常規內存)映射到內核地址空間,但超出1GB大小的物理內存(即高端內存)就不能映射到內核空間。為此,內核采取了下面的方法使得內核可以使用所有的物理內存。

      1).高端內存不能全部映射到內核空間,也就是說這些物理內存沒有對應的線性地址。不過,內核為每個物理頁框都分配了對應的頁框描述符,所有的頁框描述符都保存在mem_map數組中,因此每個頁框描述符的線性地址都是固定存在的。內核此時可以使用alloc_pages()和alloc_page()來分配高端內存,因為這些函數返回頁框描述符的線性地址。

      2).內核地址空間的后128MB專門用于映射高端內存,否則,沒有線性地址的高端內存不能被內核所訪問。這些高端內存的內核映射顯然是暫時映射的,否則也只能映射128MB的高端內存。當內核需要訪問高端內存時就臨時在這個區域進行地址映射,使用完畢之后再用來進行其他高端內存的映射。

      由于要進行高端內存的內核映射,因此直接能夠映射的物理內存大小只有896MB,該值保存在high_memory中。內核地址空間的線性地址區間如下圖所示:

      從圖中可以看出,內核采用了三種機制將高端內存映射到內核空間:永久內核映射,固定映射和vmalloc機制。

      2.物理內存管理機制

      基于物理內存在內核空間中的映射原理,物理內存的管理方式也有所不同。內核中物理內存的管理機制主要有伙伴算法,slab高速緩存和vmalloc機制。其中伙伴算法和slab高速緩存都在物理內存映射區分配物理內存,而vmalloc機制則在高端內存映射區分配物理內存。

      伙伴算法

      伙伴算法負責大塊連續物理內存的分配和釋放,以頁框為基本單位。該機制可以避免外部碎片。

      per-CPU頁框高速緩存

      內核經常請求和釋放單個頁框,該緩存包含預先分配的頁框,用于滿足本地CPU發出的單一頁框請求。

      slab緩存

      slab緩存負責小塊物理內存的分配,并且它也作為高速緩存,主要針對內核中經常分配并釋放的對象。

      vmalloc機制

      vmalloc機制使得內核通過連續的線性地址來訪問非連續的物理頁框,這樣可以最大限度的使用高端物理內存。

      3.物理內存的分配

      內核發出內存申請的請求時,根據內核函數調用接口將啟用不同的內存分配器。

      3.1 分區頁框分配器

      分區頁框分配器 (zoned page frame allocator) ,處理對連續頁框的內存分配請求。分區頁框管理器分為兩大部分:前端的管理區分配器和伙伴系統,如下圖:

      管理區分配器負責搜索一個能滿足請求頁框塊大小的管理區。在每個管理區中,具體的頁框分配工作由伙伴系統負責。為了達到更好的系統性能,單個頁框的申請工作直接通過per-CPU頁框高速緩存完成。

      該分配器通過幾個函數和宏來請求頁框,它們之間的封裝關系如下圖所示。

      這些函數和宏將核心的分配函數__alloc_pages_nodemask()封裝,形成滿足不同分配需求的分配函數。其中,alloc_pages()系列函數返回物理內存首頁框描述符,__get_free_pages()系列函數返回內存的線性地址。

      3.2 slab分配器

      slab 分配器最初是為了解決物理內存的內部碎片而提出的,它將內核中常用的數據結構看做對象。slab分配器為每一種對象建立高速緩存。內核對該對象的分配和釋放均是在這塊高速緩存中操作。一種對象的slab分配器結構圖如下:

      可以看到每種對象的高速緩存是由若干個slab組成,每個slab是由若干個頁框組成的。雖然slab分配器可以分配比單個頁框更小的內存塊,但它所需的所有內存都是通過伙伴算法分配的。

      slab高速緩存分專用緩存和通用緩存。專用緩存是對特定的對象,比如為內存描述符創建高速緩存。通用緩存則是針對一般情況,適合分配任意大小的物理內存,其接口即為kmalloc()。

      3.3 非連續內存區內存的分配

      內核通過vmalloc()來申請非連續的物理內存,若申請成功,該函數返回連續內存區的起始地址,否則,返回NULL。vmalloc()和kmalloc()申請的內存有所不同,kmalloc()所申請內存的線性地址與物理地址都是連續的,而vmalloc()所申請的內存線性地址連續而物理地址則是離散的,兩個地址之間通過內核頁表進行映射。

      vmalloc()的工作方式理解起來很簡單:

      1).尋找一個新的連續線性地址空間;

      2).依次分配一組非連續的頁框;

      3).為線性地址空間和非連續頁框建立映射關系,即修改內核頁表;

      vmalloc()的內存分配原理與用戶態的內存分配相似,都是通過連續的虛擬內存來訪問離散的物理內存,并且虛擬地址和物理地址之間是通過頁表進行連接的,通過這種方式可以有效的使用物理內存。但是應該注意的是,vmalloc()申請物理內存時是立即分配的,因為內核認為這種內存分配請求是正當而且緊急的;相反,用戶態有內存請求時,內核總是盡可能的延后,畢竟用戶態跟內核態不在一個特權級。

    看過“ 物理虛擬內存 ”的人還看了:

    1.物理與虛擬內存的區別

    2.關于虛擬內存和物理內存

    3.什么是物理內存與虛擬內存 各指什么

    4.物理內存4g設虛擬內存

    5.電腦虛擬內存怎么設置最好

    603644 主站蜘蛛池模板: 欧美精品亚洲精品日韩专区va| 2018国产大陆天天弄| 精品福利一区二区三区免费视频| 日本特黄a级高清免费大片| 国产精品99久久免费观看| 亚洲欧美日韩精品中文乱码| 亚洲成人在线免费观看| 99精品无人区乱码在线观看| 精品一区二区三区四区在线| 成人福利小视频| 国产一区二区三区不卡在线观看| 久久天堂AV综合合色蜜桃网| 欧美日韩一区二区三区四区在线观看| 欧美成人免费全部观看天天性色| 国内精品videofree720| 亚洲精品中文字幕乱码| 99久久亚洲综合精品成人网| 波多野结衣办公室33分钟| 国语自产精品视频在线区| 亚洲黄色三级网站| 91大神免费观看| 欧美人善交videosg| 国产成人一区二区三区精品久久| 亚洲av无码专区在线观看下载| 0588影视手机免费看片| 欧美一区二区三区久久综| 国产福利在线观看你懂的| 亚洲天堂一区二区三区四区| 色www永久免费| 欧美色图校园春色| 国产精品三级电影在线观看| 亚洲国产欧美国产综合一区| 99久久久国产精品免费蜜臀| 欧美最猛性xxxx高清| 国产精品videossex另类| 久久我们这里只有精品国产4| 色窝窝亚洲av网| 女让张开腿让男人桶视频| 亚洲精品成人av在线| 日本一二三精品黑人区| 日本人强jizzjizz|