探討Linux作業系統虛擬內存和物理內存的關係

2020-12-12 電子發燒友

探討Linux作業系統虛擬內存和物理內存的關係

TOMORROW 星辰 發表於 2020-12-10 16:12:20

為了高效、準確測試出該系統下,單個進程能夠申請到的最大虛存空間,所以編寫了一個Linux的測試程序。因為 64 位真的是個很可怕的數字,所以程序在申請內存空間時,先申請較大的內存塊(100G),直到沒有這麼大的內存塊,然後申請上次能申請到的內存塊的一半。重複以上步驟,直到內存塊變得足夠小(小於 100Byte)。然後結束申請內存。代碼如下:

#include#define SZ_100G (50*2147483648) //100GB 的字節數int main(){ int *p[1000000];//存放申請內存塊的指針以備釋放 int *ptem; long long int block_sz,total_sz=0; int i,j; char c='c'; printf("pid=%d\n",getpid()); getchar(); block_sz=SZ_100G; for(i=0;;i++) { printf("i=%d\n",i); p[i]=(int *)malloc(block_sz*sizeof(char)); if(NULL==p[i])//當所申請的內存塊不成功時,把內存塊大小減半重新申請 { block_sz=block_sz/2; p[i]=(int *)malloc(block_sz*sizeof(char)); } total_sz=total_sz+block_sz;//累加所申請到的內存塊 if(block_sz<100)//當內存塊小於 100 個字節時結束內存申請 break; } getchar(); ptem=p[0]; for(j=0;;j++) { if(0==j%1000) c=getchar(); if('e'==c) break; *(ptem+=(2*1024*1024))=c; } for(;i>=0;i--)//釋放所有內存塊 free(p[i]); printf("total_sz=%ldByte\n",total_sz); return 0;}

在終端 1 編譯運行上面代碼。
運行後,先在另一個終端(終端 2)執行:

cat /proc/6674/status

查看該進程的 status 文件如下圖圖一所示:

終端 1 終端 2

圖一

對於 status 文件,本文只會關注以下幾個參數:

VmPeak(進程所佔用的虛存空間最大值)

VmRSS(進程正在佔用物理內存大小)

VmSwap(進程佔用交換區大小)

然後回車開始申請內存,當終端停止輸出數字時,再次在終端 2 執行:

cat /proc/6674/status

得到下圖圖二輸出:

終端 1 終端 2

圖二

對比圖一和圖二中的 VmPeak:

137438953320K – 12044K = 140737475866624 Byte

= 111 1111 1111 1111 1111 1111 0100 0001 0111 0000 0000 0000(B) Byte

是的,如果你沒有眼花,你數到上面得到的是一個 47 位!!!!二進位數。

47 位什麼概念?大概是 128TB = 128*1024GB !!! (試問現在誰的個人電腦有這麼大的硬碟??更不要說內存)

一個進程能夠申請到這麼恐怖的內存空間?這不但超過了物理內存、超過了物理內存+交換區、還超過了硬碟大小啊。這不科學啊。

但是從 status 讀出來的數據錯不了的。

首先,虛擬內存,顧名思義,虛擬的、並不是事實上存在,在一個進程的虛存空間裡,只存在進程自己和系統內核,而不存在其他進程。這是為了方便編程和提高物理內存利用率而創造出來的一種機制(在過去內存是很貴的)。虛擬內存中對應著的是邏輯地址,邏輯地址通過作業系統和硬體的配合映射到物理內存上。(這裡就不在多說虛擬內存的定義。如果把段頁式內存管理機制理解後,虛擬內存也就理解了。關於段頁式內存管理介紹可參考:深入理解作業系統之——分頁式存儲管理,深入理解作業系統之——段頁式存儲器管理。)

其二,交換區,實際上就是物理內存不夠用時,虛存空間的數據就必須映射到交換區上。

那麼單個進程所能申請的最大虛存空間理應不會超過物理內存和交換區的和。然而實際卻是超過那麼多。

然後,網上查閱相關資料,msdn 上看到了相關解釋。

傳送門:https://docs.microsoft.com/zh-cn/windows-hardware/drivers/gettingstarted/virtual-address-spaces

該文章介紹到,Windows 32 系統下,虛擬內存中,用戶空間佔用了低地址 2G 的空間,系統內核佔用了高地址 2G 空間。總共虛存空間就是 2^32Byte。

圖三

那麼 64 位系統中,就系統而言,總共的虛存空間應當是 2^64Byte?

在該文章下面還有 Windows 64 位系統的虛存空間介紹,如下圖圖四所示。從圖中看到用戶虛存空間 8TB+系統空間 248TB=256TB=2^48 Byte ,這個數字似乎和上面所測得的單個進程能夠申請到的最大虛存空間的數字有點接近了。

圖四

注意看圖四,還可以發現 64 位系統中還有很大很大的虛存空間保留沒有被使用的。從這個出發繼續查閱資料,然後找到了關於目前 64 位 CPU 的相關說明。由於目前還遠遠用不到 64 位那麼大的空間,所以 AMD 64 位 CPU 目前只用了 48 位的尋址。而 Intel 的 64 位 CPU 是和 AMD 交叉授權,所以 Intel 64CPU 也同樣只採用 48 位尋址。所以圖三的保留空間就得到了解釋。

再回到原先的問題,現在知道了就 64 位系統而言,虛擬內存空間是可以達到 2^48Byte 那麼大的,參考 Windows 64 位系統虛存空間結構,可以猜測Linux 64 位系統下,用戶虛存空間和系統內核虛存空間分布和 Windows 是相似的,只是兩者大小比例有所差別。(因為找了很久,沒有找到Linux的官方文檔說明,只找到很舊的、32 位。所以不能提供準確的參考,如果有讀者找到,希望可以告訴作者一下補上)。

不過,到現在,還有問題沒有解決,為什麼所申請的虛存空間會比物理內存與交換區的和大?

現在回到一開始沒有運行完的程序,在終端 1 回車繼續運行程序,程序接著會對所申請到的第一個 100G 內存塊每隔 2M 空間進行寫操作,每回車一次,會寫 1000 次。回車幾次後,在終端 2 再執行:

cat /proc/6674/status

得到下圖圖五:

圖五

由圖五可以看到正在使用的物理內存 VmRSS 變小了,正在使用的交換區空間 VmSwap 迅速增大。但是兩者之和是在一直增加的,這就說明,申請到的虛擬內存在未被使用之前,它只是一個數字,並沒有實際的物理內存和交換區與之相對應。當對虛存進行寫操作時,系統就會逐步分配物理內存,而物理內存的數據又會可能被系統調到交換區。現在問題逐漸明了了。

如果我不停地對虛存空間進行寫操作會怎樣,為了解決疑惑,在終端 1 不停回車,偶爾在終端 2 中查看 status 文件中的狀態,寫到一定程度後,終端 1 出現了

[1] 7893 killed a.out

如圖六所示:

圖六

在進程結束之前查看到的 status 文件顯示 VmRSS+VmSwap 約等 1.8G,加上系統佔用和其他進程佔用,那麼說此時物理內存和交換區已經接近極限了。再繼續運行寫的時候,作業系統為了系統的正常運行選擇把這個進程殺死了。那麼所有的疑問也解決了。

系統所允許的申請的虛存空間是可以超過物理內存與交換區的和的。但是當進程所佔用的物理內存加上交換區影響到了系統的正常運行就會被系統殺死。
編輯:hfy

打開APP閱讀更多精彩內容

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容圖片侵權或者其他問題,請聯繫本站作侵刪。 侵權投訴

相關焦點

  • 虛擬內存怎麼設置最好
    這是設置虛擬內存的方法。1.右鍵單擊「計算機」,然後在菜單欄中選擇「屬性」。2.接下來選擇左側欄的「高級系統設置」。4.然後將界面切換到「高級」窗口,然後單擊虛擬內存列下的「更改」按鈕。5.取消選中自動管理以上所有驅動器的頁面文件大小的選項,然後選擇以下自定義選項。然後,對於初始大小和最大值,我們可以輸入實際內存的1.5到3倍。例如,實際內存為1G,最小值可以設置為1.5G,最大值為3G。點擊「確定」。
  • GBase 8a MPP Cluster 安裝部署——作業系統配置建議
    網絡及內核參數設置進行linux作業系統的網絡及內核參數的優化設置,設置方式為通過在/etc/sysctl.conf文件中添加或修改配置項。參數建議為物理內存的5%~10%,最大8G。3. ulimit設置Suse作業系統11下,默認對進程的虛擬內存以及物理內存的使用有限制。
  • 從串口驅動到Linux驅動模型,想轉Linux的必會!
    驅動與底層硬體直接打交道,按照硬體設備的具體工作方式,讀寫設備的寄存器,完成設備的輪詢、中斷處理、DMA通信,進行物理內存向虛擬內存的映射等,最終讓通信設備能收發數據,讓顯示設備能顯示文字和畫面,讓存儲設備能記錄文件和數據。Linux設備驅動是對底層硬體資源的抽象。對上層的作業系統其他服務提供一個良好的接口。讓其他服務可以把一個特定的硬體。或是一種機制當做一個文件使用。
  • vxworks和linux有什麼區別
    server關係,這種服務並不一定非得留在內核中,它本身也可以被設計實現成「服務進程」,其中必須留在內核中的部分只有進程間的通信,如果把這些服務從內核轉移到進程的層次上,那麼內核本身的結構就可以大大減小和減化,而各個服務進程也可以單獨設計、實現及調試。
  • 伺服器內存佔用高怎麼辦
    伺服器隨著運行時間的增加,佔用內存會逐漸增加。如果伺服器內存小,就很容易出現內存佔滿,系統變慢,甚至是卡死的情況。一個辦法是增加物理內存,但這涉及到費用、停機、開機箱等。這裡有一個處理方案,可供借鑑。效果好的話,可以不用買內存條了哈哈。
  • 阿里面試官問我Java線程和作業系統線程什麼關係
    用戶態的線程 第一階段: 其實早期的時候,作業系統是沒有線程的概念,線程是後面加進來的,作業系統剛開始只有進程,作業系統分配資源的最小單位是進程,進程與進程之間相關隔離,每個進程有自己的內存空間,文件描述符,CPU調度以進程作為最小調度單元; 第二階段: 初期的多線程
  • Python實現內存監控系統
    Python實現內存監控系統: 思路:通過系統命令或作業系統文件獲取到內存信息 (linux 內存信息存在/proc/meminfo文件中,mac os 通過命令vm_stat命令可以查看) 並將獲取到信息保存到資料庫中
  • 我和面試官間關於作業系統的一場對弈!寫了很久,希望對你有幫助
    下圖是 Java 內存區域,我們從 JVM 的角度來說一下線程和進程之間的關係吧!我們編程一般只有可能和邏輯地址打交道,比如在 C 語言中,指針裡面存儲的數值就可以理解成為內存裡的一個地址,這個地址也就是我們說的邏輯地址,邏輯地址由作業系統決定。物理地址指的是真實物理內存中地址,更具體一點來說就是內存地址寄存器中的地址。物理地址是內存單元真正的地址。3.6 CPU 尋址了解嗎?為什麼需要虛擬地址空間?
  • [ARM筆記]內存管理單元地址變換過程
    虛擬存儲器從邏輯上對內存容量進行了擴充,用戶看到的大容量只是一種感覺,是虛的。在32位的CPU系統中,這個虛擬內存的地址範圍是0~0xffff_ffff,我們把這個地址範圍稱為虛擬地址空間,其中的某個地址稱為虛擬地址。與虛擬地址空間、虛擬地址對應的是物理地址空間、物理地址,它們對應實際的內存。
  • VPS、雲伺服器、虛擬主機、物理伺服器的含義與區別
    VPS(Virtual Private Server 虛擬專用伺服器)技術,由於有很多的物理伺服器其實使用率很低,平均CPU的使用率一般都在20%以下。在這樣的環境下就出現了將一臺物理伺服器分割成多個虛擬專享伺服器的優質服務。實現VPS的技術分為容器技術和虛擬化技術。
  • linux伺服器內存異常,究竟在哪消耗了2.5G?
    linux伺服器內存異常,究竟在哪消耗了2.5G? 今天這個問題是未解之謎,還是挺神奇的,一起來看看吧~以下是一臺2核4G的伺服器,其中伺服器上沒運行任何程序,但4G內存就用了2.5G 作者:波波說運維來源:今日頭條|2020-07-28 09:48
  • 作業系統模型與樂高積木 · OSDI 2018
    因為現有的作業系統都無法處理類似的場景,所以這篇論文提出了一種分離內核(Split kernel)的作業系統模型來管理和控制底層的硬體資源。內存mComponent 主要會用於處理三種類型的數據:匿名內存(堆和棧)、內存映射文件和存儲緩存區,它會同時管理虛擬和物理內存空間的分配、釋放以及映射。
  • Unix和Linux作業系統有什麼區別?
    說Unix是作業系統的鼻祖一點都不為過,Linux可以說是在Unix下創新發展而來。他們有很多共同的地方,也有很多不同的地方。1、Unix和lLinux的歷史淵源Unix和Linux兩個系統都是起源於個人興趣愛好,只是時間先後不同而已。①、Unix系統淵源Unix作業系統是由肯湯普森和丹尼斯裡奇這兩位大神發明的,他們被稱為Unix之父。
  • 基於MCU無作業系統,簡單而又強大的內存管理方法
    星標公眾號,不錯過精彩內容 作者 | piaolingtear 編排 | strongerHuang 內存管理一般在作業系統中才有,比如:Linux、Windows這些作業系統都有內存管理器,包括大部分RTOS同樣也有內存管理。
  • linux 虛擬主機好嗎
    linux 虛擬主機好嗎?linux 虛擬主機是採用Linux系統搭建的虛擬主機,是企業和個人都非常喜歡使用的虛擬主機種類。運行穩定,對軟體的兼容遠超Windows系統。目前,市面上大多數病毒和惡意程序都是針對win系統開發,而Linux系統對此先天免疫。又由於代碼開源,即使linux不幸感染病毒,維護人員也容易查出運行異常之處,並加以解決。平時,linux系統也可利用自帶防火牆、入侵檢測和安全認證等工具及時修補漏洞,提高系統安全性。
  • Linux基礎教程:CentOS開機流程詳解
    系統找到BIOS所指定的硬碟的MBR後,就會將其複製到物理內存中,被複製到物理內存的內容就是Boot Loader(lilo或者grub)。 第三步:啟動Boot Loader Boot Loader 就是在作業系統內核運行之前運行的一段小程序。
  • Hyper-V虛擬化技術,可在Windows 10中創建虛擬機,安裝作業系統
    通過虛擬化技術可以非常方便地安裝、使用或測試各種不同類型的作業系統或組建網絡環境,提高對計算機硬體資源的利用率,虛擬化技術有著物理計算機無法比擬的靈活性和安全性。微軟在Windows 10中提供了Hyper-V虛擬化技術,利用該技術可以在Windows 10中創建虛擬機並在虛擬機中安裝作業系統,虛擬硬碟則為在虛擬機中安裝作業系統和存儲數據提供了方便,而且也可以用於物理計算機。
  • 電腦內存不足怎麼辦?
    電腦內存不足怎麼辦? 如果沒有設置讓Windows管理虛擬內存或者禁用虛擬內存,那麼計算機可能無法正常工作,也可能收到「內存不足」的消息,或在運行某程序時出現相同的錯誤消息。
  • 256GB的Gen-Z內存模組亮相SC2019
    在SC2019的美國科羅拉多計算機展覽會上,廠商展示256GB Gen-Z內存模組,全稱為緩存一致性內存語義標準,能在CXL等標準節點的內部工作,後者能夠為內存、存儲、加速器以及其它連接到伺服器的交換節點服務。
  • 預算5000元 研究生打造8G內存學習用機
    和大多數學生裝機的目的不同,他裝機的目的是用來運行VMware ESXi(一種具有高級資源管理功的虛擬主機作業系統)進行軟體的測試與數據的計算。VMware ESXi對硬體的要求很高,為了能夠更好的運行這個作業系統,他決心省吃儉用,組裝一臺專用的實驗用機。