0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

對(duì)物理內(nèi)存空間與線性空間了解

j4AI_wujianying ? 來(lái)源:未知 ? 作者:工程師郭婷 ? 2018-06-30 10:58 ? 次閱讀

硬件工程師和普通用戶看來(lái),內(nèi)存就是插在或固化在主板上的內(nèi)存條,它們有一定的容量——比如64 MB。但在應(yīng)用程序員眼中,并不過(guò)度關(guān)心插在主板上的內(nèi)存容量,而是他們可以使用的內(nèi)存空間——他們可以開(kāi)發(fā)一個(gè)需要占用1 GB內(nèi)存的程序,并讓其在OS平臺(tái)上運(yùn)行,哪怕這臺(tái)運(yùn)行主機(jī)上只有128 MB的物理內(nèi)存條。而對(duì)于OS開(kāi)發(fā)者而言,則是介于二者之間,他們既需要知道物理內(nèi)存的細(xì)節(jié),也需要提供一套機(jī)制,為應(yīng)用程序員提供另一個(gè)內(nèi)存空間,這個(gè)內(nèi)存空間的大小可以和實(shí)際的物理內(nèi)存大小之間沒(méi)有任何關(guān)系。

我們將主板上的物理內(nèi)存條所提供的內(nèi)存空間定義為物理內(nèi)存空間;將應(yīng)用程序員看到的內(nèi)存空間定義為線性空間。物理內(nèi)存空間大小在不同的主機(jī)上可以是不一樣的,隨著主板上所插的物理內(nèi)存條的容量不同而不同;但為應(yīng)用程序員提供的線性空間卻是固定的,不會(huì)隨物理內(nèi)存的變化而變化,這樣才能保證應(yīng)用程序的可移植性。盡管物理內(nèi)存的大小可以影響應(yīng)用程序運(yùn)行的性能,并且很多情況下對(duì)物理內(nèi)存的大小有一個(gè)最低要求,但這些因素只是為了讓一個(gè)OS可以正常的運(yùn)行。

線性空間的大小在32-bit平臺(tái)上為4 GB的固定大小,對(duì)于每個(gè)進(jìn)程都是這樣(一個(gè)應(yīng)用可以是多進(jìn)程的,在OS眼中,是以進(jìn)程為單位的)。也就是說(shuō)線性空間不是進(jìn)程共享的,而是進(jìn)程隔離的,每個(gè)進(jìn)程都有相同大小的4 GB線性空間。一個(gè)進(jìn)程對(duì)于某一個(gè)內(nèi)存地址的訪問(wèn),與其它進(jìn)程對(duì)于同一內(nèi)存地址的訪問(wèn)絕不沖突。比如,一個(gè)進(jìn)程讀取線性空間地址1234ABCDh可以讀出整數(shù)8,而另外一個(gè)進(jìn)程讀取線性空間地址1234ABCDh可以讀出整數(shù)20,這取決于進(jìn)程自身的邏輯。

在任意一個(gè)時(shí)刻,在一個(gè)CPU上只有一個(gè)進(jìn)程在運(yùn)行。所以對(duì)于此CPU來(lái)講,在這一時(shí)刻,整個(gè)系統(tǒng)只存在一個(gè)線性空間,這個(gè)線性空間是面向此進(jìn)程的。當(dāng)進(jìn)程發(fā)生切換的時(shí)候,線性空間也隨著切換。所以結(jié)論就是每個(gè)進(jìn)程都有自己的線性空間,只有此進(jìn)程運(yùn)行的時(shí)候,其線性空間才被運(yùn)行它的CPU所知。在其它時(shí)刻,其線性空間對(duì)于CPU來(lái)說(shuō),是不可知的。所以盡管每個(gè)進(jìn)程都可以有4 GB的線性空間,但在CPU眼中,只有一個(gè)線性空間的存在。線性空間的變化,隨著進(jìn)程切換而變化。

盡管線性空間的大小和物理內(nèi)存的大小之間沒(méi)有任何關(guān)系,但使用線性空間的應(yīng)用程序最終還是要運(yùn)行在物理內(nèi)存中。應(yīng)用所給出的任何線性地址最終必須被轉(zhuǎn)化為物理地址,才能夠真正的訪問(wèn)物理內(nèi)存。所以,線性內(nèi)存空間必須被映射到物理內(nèi)存空間中,這個(gè)映射關(guān)系需要通過(guò)使用硬件體系結(jié)構(gòu)所規(guī)定的數(shù)據(jù)結(jié)構(gòu)來(lái)建立。我們不妨先稱其為映射表。一個(gè)映射表的內(nèi)容就是某個(gè)線性內(nèi)存空間和物理內(nèi)存空間之間的映射關(guān)系。OS Kernel一旦告訴某個(gè)CPU一個(gè)映射表的位置,那么這個(gè)CPU需要去訪問(wèn)一個(gè)線性空間地址時(shí),就根據(jù)這張映射表的內(nèi)容,將這個(gè)線性空間地址轉(zhuǎn)化為物理空間地址,并將此物理地址送到地址線,畢竟地址線只知道物理地址。

所以,我們很容易得出一個(gè)結(jié)論,如果我們給出不同的映射表,那么CPU將某一線性空間地址轉(zhuǎn)化的物理地址也會(huì)不同。所以我們?yōu)槊恳粋€(gè)進(jìn)程都建立一張映射表,將每個(gè)進(jìn)程的線性空間根據(jù)自己的需要映射到物理空間上。既然某一時(shí)刻在某一CPU上只能有一個(gè)應(yīng)用在運(yùn)行,那么當(dāng)任務(wù)發(fā)生切換的時(shí)候,將映射表也更換為響應(yīng)的映射表就可以實(shí)現(xiàn)每個(gè)進(jìn)程都有自己的線性空間而互不影響。所以,在任意時(shí)刻,對(duì)于一個(gè)CPU來(lái)說(shuō),也只需要有一張映射表,以實(shí)現(xiàn)當(dāng)前進(jìn)程的線性空間到物理空間的轉(zhuǎn)化。

1. OS Kernel Space & Process Space

由于OS Kernel在任意時(shí)刻都必須存在于內(nèi)存中,而進(jìn)程卻可以切換,所以在任意時(shí)刻,內(nèi)存中都存在兩部分,OS Kernel和用戶進(jìn)程。而在任意時(shí)刻,對(duì)于一個(gè)CPU來(lái)說(shuō)只存在一個(gè)線性空間,所以這個(gè)線性空間必須被分成兩部分,一部分供OS Kernel使用,另一部分供用戶進(jìn)程使用。既然OS Kernel在任何時(shí)候都占用線性空間中的一部分,那么對(duì)于所有進(jìn)程的線性空間而言,它們?yōu)镺S Kernel所留出的線性空間可以是完全相同的,也就是說(shuō),它們各自的映射表中,也分為兩部分,一部分是進(jìn)程私有映射部分,對(duì)于OS Kernel映射部分的內(nèi)容則完全相同。

從這個(gè)意義上來(lái)說(shuō),我們可以認(rèn)為,對(duì)于所有的進(jìn)程而言,它們共享OS Kernel所占用的線性空間部分,而每個(gè)進(jìn)程又各自有自己私有的線性空間部分。假如,我們將任意一個(gè)4 GB線性空間分割為1 GB的OS Kernel空間部分和3 GB的進(jìn)程空間部分,那么所有進(jìn)程的4 GB線性空間中1 GB的OS Kernel空間是共享的,而剩余的3 GB進(jìn)程空間部分則是各個(gè)進(jìn)程私有的。Linux就是這么做的,而Windows NT則是讓OS Kernel和進(jìn)程各使用2 GB線性空間。

2. Segment Mapping & Page Mapping

所有的線性空間的內(nèi)容只有被放置到物理內(nèi)存中才能夠被真正的運(yùn)行和操作。所以,盡管OS Kernel和進(jìn)程都被放在線性空間中,但它們最終必須被放置到物理內(nèi)存中。所以O(shè)S Kernel和所有的進(jìn)程都最終共享物理內(nèi)存。在現(xiàn)階段,物理內(nèi)存遠(yuǎn)沒(méi)有線性空間那么大——線性空間是4 GB,而物理內(nèi)存空間往往只有幾百兆,甚至更小。另外即使物理內(nèi)存有4 GB,但由于每個(gè)進(jìn)程都可以有3 GB線性空間(假如進(jìn)程私有線性空間是3 GB的話),如果把所有進(jìn)程的線性空間內(nèi)容都放在物理內(nèi)存中,明顯是不現(xiàn)實(shí)的。所以O(shè)S Kernel必須將某些進(jìn)程暫時(shí)用不到的數(shù)據(jù)或代碼放在物理內(nèi)存之外,將有限的內(nèi)存提供給當(dāng)前最需要的進(jìn)程。另外,由于OS Kernel在任何時(shí)候都有可能運(yùn)行,所以O(shè)S Kernel最好被永遠(yuǎn)放在物理內(nèi)存中。我們僅僅將進(jìn)程數(shù)據(jù)進(jìn)行換入換出。

從線性空間到物理空間的映射需要映射表,映射表的內(nèi)容是將某段線性空間映射到相同大小的物理內(nèi)存空間上。從理論上,我們可以使用兩種映射方法:變長(zhǎng)映射,和定長(zhǎng)映射。變長(zhǎng)映射指的是根據(jù)不同的需要,將一個(gè)一個(gè)變長(zhǎng)段映射到物理內(nèi)存上,其格式可以如下(線性空間段起始地址,物理空間段起始地址,段長(zhǎng)度)。假如一個(gè)進(jìn)程有3個(gè)段:10M的數(shù)據(jù)段,5M的代碼段,和8K的堆棧段,那么就可以在映射表中建立3項(xiàng)內(nèi)容,每一項(xiàng)針對(duì)一個(gè)段。這看起來(lái)沒(méi)有問(wèn)題。但假如現(xiàn)在我們的實(shí)際的內(nèi)存只有32M,其中10M被內(nèi)核占用,留給進(jìn)程的物理空間只有22M,那么此進(jìn)程在運(yùn)行時(shí),就占據(jù)了10M+5M+8K的內(nèi)存空間。隨后當(dāng)進(jìn)程發(fā)生切換時(shí),假如另一個(gè)進(jìn)程和其有相同的內(nèi)存要求,那么剩余的22M-(10M+5M+8K)明顯就不夠用了,這時(shí)只能將原進(jìn)程的某些段換出,并且必須是整段的換出。這就意味著我們必須至少換出一個(gè)10M的數(shù)據(jù)段,而換出的成本很高,因?yàn)槲覀儽仨殞⑦@10M的內(nèi)容拷貝到磁盤上,磁盤I/O是很慢的。

所以,使用變長(zhǎng)的段映射的結(jié)果就是一個(gè)段要么被全部換入,要么被全部換出。但在現(xiàn)實(shí)中,一個(gè)程序中并非所有的代碼和數(shù)據(jù)都能夠被經(jīng)常訪問(wèn),往往被經(jīng)常訪問(wèn)的只占全部代碼數(shù)據(jù)的一部分,甚至是一小部分。所以更有效的策略是我們最好只換出那些并不經(jīng)常使用的部分,而保留那些經(jīng)常被使用的部分。而不是整個(gè)段的換入換出。這樣可以避免大塊的慢速磁盤操作。

這就是定長(zhǎng)映射策略,我們將內(nèi)存空間分割為一個(gè)個(gè)定長(zhǎng)塊,每個(gè)定長(zhǎng)塊被稱為一個(gè)頁(yè)。映射表的基本格式為(物理空間頁(yè)起始地址),由于頁(yè)是定長(zhǎng)的,所以不需要指出它的長(zhǎng)度,另外,我們不需要在映射表中指定線性地址,我們可以將線性地址作為索引,到映射表中檢索出相應(yīng)的物理地址。當(dāng)使用頁(yè)時(shí),其策略為:當(dāng)換出的時(shí)候,我們只將那些不活躍的,也就是不經(jīng)常使用的頁(yè)換出,而保留那些活躍的頁(yè)。在換入的時(shí)候,只有被請(qǐng)求訪問(wèn)的頁(yè)才被換入,沒(méi)有被請(qǐng)求訪問(wèn)的頁(yè)將永遠(yuǎn)不會(huì)被換入到物理內(nèi)存。這就是請(qǐng)求頁(yè)(Demand Page)算法的核心思想。

這就引出一個(gè)頁(yè)大小的問(wèn)題:首先我們不可能以字節(jié)為單位,這樣映射表的大小和線性空間大小相同——假如整個(gè)線性空間都被映射的話——我們不可能將全部線性空間用作存放這個(gè)映射表。由此,我們也可以得知,頁(yè)越小,則映射表的容量越大。而我們不能讓映射表占用太多的空間。但如果頁(yè)太大,則面臨著和不定長(zhǎng)段映射同樣的問(wèn)題,每次換出一個(gè)頁(yè),都需要大量的磁盤操作。另外,由于為一個(gè)進(jìn)程分配內(nèi)存的最小單位是頁(yè),假如我們的頁(yè)大小為4 MB,那么即使一個(gè)進(jìn)程只需要使用4 KB的內(nèi)存,也不得不占用整個(gè)4 MB頁(yè),這明顯是一種很大的浪費(fèi)。所以我們必須在兩者之間進(jìn)行折衷,一般平臺(tái)所規(guī)定的頁(yè)大小為1 KB到8 KB,IA-32所規(guī)定的頁(yè)大小為4 KB。(IA-32也支持4 MB頁(yè),你可以根據(jù)你的OS的用途進(jìn)行選擇,一般都是使用4 KB頁(yè))。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • cpu
    cpu
    +關(guān)注

    關(guān)注

    68

    文章

    10807

    瀏覽量

    210854
  • 內(nèi)存
    +關(guān)注

    關(guān)注

    8

    文章

    2978

    瀏覽量

    73818

原文標(biāo)題:硬件工程師對(duì)于程序空間的理解

文章出處:【微信號(hào):wujianying_danpianji,微信公眾號(hào):?jiǎn)纹瑱C(jī)精講吳鑒鷹】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    Linux內(nèi)存點(diǎn)滴 用戶進(jìn)程內(nèi)存空間

    程的VM(虛擬內(nèi)存),但并不表示這個(gè)進(jìn)程占用了這么多的RAM(物理內(nèi)存)。這個(gè)空間有多大?命令top輸出的VIRT值告訴了我們各個(gè)進(jìn)程內(nèi)存空間
    發(fā)表于 08-14 16:23

    SigmaStudio Delay模塊把MAX設(shè)置為1500時(shí)占用了6000的data32的內(nèi)存空間

    在使用SigmaStudio 3.9的DELAY模塊時(shí),當(dāng)把MAX設(shè)置為1500時(shí),合理應(yīng)該就是占用1500的data32 ram空間,但現(xiàn)在在編譯輸出結(jié)果中卻看到是占用了6000的data32 的內(nèi)存空間,為什么會(huì)有這樣的問(wèn)題呢?應(yīng)該如何解決?謝謝!取樣率設(shè)置為48K。
    發(fā)表于 03-06 06:13

    DM8127使用SWOSD_TI_alloc()分配內(nèi)存空間怎么加大?

    DM8127使用SWOSD_TI_alloc()分配內(nèi)存空間不夠,請(qǐng)問(wèn)在什么文件里怎樣修改加大內(nèi)存空間???
    發(fā)表于 04-16 10:56

    Linux用戶空間與內(nèi)核空間的區(qū)別?

    對(duì)于提供了MMU(存儲(chǔ)管理器,輔助操作系統(tǒng)進(jìn)行內(nèi)存管理,提供虛實(shí)地址轉(zhuǎn)換等硬件支持)的處理器而言,Linux提供了復(fù)雜的存儲(chǔ)管理系統(tǒng),使得進(jìn)程所能訪問(wèn)的內(nèi)存達(dá)到4GB。進(jìn)程的4GB內(nèi)存空間被人
    發(fā)表于 06-05 04:35

    如何與ctypes庫(kù)創(chuàng)建的數(shù)組共享內(nèi)存空間?

    。那么,如何使用ctypes庫(kù)定義一個(gè)與numpy共享內(nèi)存空間的數(shù)組變量呢?仍以上面的例子,定義一個(gè)uint8類型的數(shù)組b,與a數(shù)組共享內(nèi)存區(qū)域,可使用下面的代碼:b = (c_uint8*len(a
    發(fā)表于 01-15 16:01

    stm32 使用u*** host庫(kù)占用內(nèi)存空間很大?。?!

    如何解決stm32 使用u*** host庫(kù)占用內(nèi)存空間很大的問(wèn)題呢???
    發(fā)表于 01-22 16:44

    Linux虛擬內(nèi)存物理內(nèi)存的深刻分析

    進(jìn)程這種情況,浪費(fèi)內(nèi)存!第二層理解每個(gè)進(jìn)程的4G內(nèi)存空間只是虛擬內(nèi)存空間,每次訪問(wèn)內(nèi)存空間的某個(gè)地址,都需要把地址翻譯為實(shí)際物理
    發(fā)表于 05-31 08:00

    RTThread的動(dòng)態(tài)內(nèi)存空間該如何去分配呢

    關(guān)于rtt的動(dòng)態(tài)內(nèi)存空間分配,想問(wèn)一下以下我的幾點(diǎn)理解是對(duì)的嗎1、我看RTT NANO和MASTER版本的動(dòng)態(tài)內(nèi)存分配好像不太一樣,我的理解是MASTER版本的動(dòng)態(tài)內(nèi)存位置是從ZI段結(jié)束地址到RAM
    發(fā)表于 08-31 14:34

    在stm32f429上的輕量級(jí)算法運(yùn)行時(shí)所用的內(nèi)存空間要怎么得到呢?

    在stm32f429上跑了幾個(gè)輕量級(jí)算法,相比較一下他們的性能,所以向研究下算法運(yùn)行時(shí)占據(jù)的內(nèi)存空間,這個(gè)內(nèi)存空間要怎么得到呢
    發(fā)表于 03-14 10:38

    MCU中怎么申請(qǐng)一段固定地址的內(nèi)存空間?

    MCU中怎么申請(qǐng)一段固定地址的內(nèi)存空間
    發(fā)表于 10-09 07:35

    freertos怎么釋放任務(wù)的內(nèi)存空間?

    freertos怎么釋放任務(wù)的內(nèi)存空間
    發(fā)表于 10-12 07:20

    內(nèi)存就是插在或固化在主板上的內(nèi)存條嗎?程序空間還有什么理解?

    個(gè)需要占用1 GB內(nèi)存的程序,并讓其在OS平臺(tái)上運(yùn)行,哪怕這臺(tái)運(yùn)行主機(jī)上只有128 MB的物理內(nèi)存條。而對(duì)于OS開(kāi)發(fā)者而言,則是介于二者之間,他們既需要知道物理
    的頭像 發(fā)表于 07-17 17:35 ?1.4w次閱讀

    如何讓你的手機(jī)省出內(nèi)存空間

    大家都知道,手機(jī)使用久了就會(huì)變得很卡頓,除了手機(jī)本身“老化”之外,還有一個(gè)重要的原因就是內(nèi)存堆積的太多了。事實(shí)上占用手機(jī)內(nèi)存的無(wú)非就是照片、視頻、微信等等,如果好好處理一下這幾個(gè)方面的問(wèn)題,相信你的手機(jī)一定能省出不少內(nèi)存空間,下
    的頭像 發(fā)表于 02-13 14:07 ?4168次閱讀

    內(nèi)存是怎么映射到物理地址空間的?內(nèi)存是連續(xù)分布的嗎?

    如果我們將兩個(gè)4G內(nèi)存插入內(nèi)存插槽,得到的內(nèi)存地址空間是0到8G嗎?是不是0到4G是第一根內(nèi)存,4到8G是第二根
    的頭像 發(fā)表于 06-30 15:59 ?3123次閱讀
    <b class='flag-5'>內(nèi)存</b>是怎么映射到<b class='flag-5'>物理</b>地址<b class='flag-5'>空間</b>的?<b class='flag-5'>內(nèi)存</b>是連續(xù)分布的嗎?

    java虛擬機(jī)內(nèi)存包括遠(yuǎn)空間內(nèi)存

    Java虛擬機(jī)(JVM)內(nèi)存是Java程序執(zhí)行時(shí)所使用的內(nèi)存空間的總稱,包括了Java堆、方法區(qū)、本地方法棧、虛擬機(jī)棧和程序計(jì)數(shù)器等多個(gè)部分。在這些內(nèi)存空間中,并不包含“遠(yuǎn)空間內(nèi)存”的
    的頭像 發(fā)表于 12-05 14:15 ?367次閱讀