為了高效、準(zhǔn)確測試出該系統(tǒng)下,單個進(jìn)程能夠申請到的最大虛存空間,所以編寫了一個Linux的測試程序。因為 64 位真的是個很可怕的數(shù)字,所以程序在申請內(nèi)存空間時,先申請較大的內(nèi)存塊(100G),直到?jīng)]有這么大的內(nèi)存塊,然后申請上次能申請到的內(nèi)存塊的一半。重復(fù)以上步驟,直到內(nèi)存塊變得足夠?。ㄐ∮?100Byte)。然后結(jié)束申請內(nèi)存。代碼如下:
#include#define SZ_100G (50*2147483648) //100GB 的字節(jié)數(shù) int main() { int *p[1000000];//存放申請內(nèi)存塊的指針以備釋放 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])//當(dāng)所申請的內(nèi)存塊不成功時,把內(nèi)存塊大小減半重新申請 { block_sz=block_sz/2; p[i]=(int *)malloc(block_sz*sizeof(char)); } total_sz=total_sz+block_sz;//累加所申請到的內(nèi)存塊 if(block_sz<100)//當(dāng)內(nèi)存塊小于 100 個字節(jié)時結(jié)束內(nèi)存申請 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--)//釋放所有內(nèi)存塊 free(p[i]); printf("total_sz=%ldByte\n",total_sz); return 0; }
在終端 1 編譯運(yùn)行上面代碼。
運(yùn)行后,先在另一個終端(終端 2)執(zhí)行:
cat /proc/6674/status
查看該進(jìn)程的 status 文件如下圖圖一所示:
終端 1 終端 2
圖一
對于 status 文件,本文只會關(guān)注以下幾個參數(shù):
VmPeak(進(jìn)程所占用的虛存空間最大值)
VmRSS(進(jìn)程正在占用物理內(nèi)存大小)
VmSwap(進(jìn)程占用交換區(qū)大?。?/p>
然后回車開始申請內(nèi)存,當(dāng)終端停止輸出數(shù)字時,再次在終端 2 執(zhí)行:
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
是的,如果你沒有眼花,你數(shù)到上面得到的是一個 47 位!!!!二進(jìn)制數(shù)。
47 位什么概念?大概是 128TB = 128*1024GB !!! (試問現(xiàn)在誰的個人電腦有這么大的硬盤??更不要說內(nèi)存)
一個進(jìn)程能夠申請到這么恐怖的內(nèi)存空間?這不但超過了物理內(nèi)存、超過了物理內(nèi)存+交換區(qū)、還超過了硬盤大小啊。這不科學(xué)啊。
但是從 status 讀出來的數(shù)據(jù)錯不了的。
首先,虛擬內(nèi)存,顧名思義,虛擬的、并不是事實上存在,在一個進(jìn)程的虛存空間里,只存在進(jìn)程自己和系統(tǒng)內(nèi)核,而不存在其他進(jìn)程。這是為了方便編程和提高物理內(nèi)存利用率而創(chuàng)造出來的一種機(jī)制(在過去內(nèi)存是很貴的)。虛擬內(nèi)存中對應(yīng)著的是邏輯地址,邏輯地址通過操作系統(tǒng)和硬件的配合映射到物理內(nèi)存上。(這里就不在多說虛擬內(nèi)存的定義。如果把段頁式內(nèi)存管理機(jī)制理解后,虛擬內(nèi)存也就理解了。關(guān)于段頁式內(nèi)存管理介紹可參考:深入理解操作系統(tǒng)之——分頁式存儲管理,深入理解操作系統(tǒng)之——段頁式存儲器管理。)
其二,交換區(qū),實際上就是物理內(nèi)存不夠用時,虛存空間的數(shù)據(jù)就必須映射到交換區(qū)上。
那么單個進(jìn)程所能申請的最大虛存空間理應(yīng)不會超過物理內(nèi)存和交換區(qū)的和。然而實際卻是超過那么多。
然后,網(wǎng)上查閱相關(guān)資料,msdn 上看到了相關(guān)解釋。
傳送門:https://docs.microsoft.com/zh-cn/windows-hardware/drivers/gettingstarted/virtual-address-spaces
該文章介紹到,Windows 32 系統(tǒng)下,虛擬內(nèi)存中,用戶空間占用了低地址 2G 的空間,系統(tǒng)內(nèi)核占用了高地址 2G 空間??偣蔡摯婵臻g就是 2^32Byte。
圖三
那么 64 位系統(tǒng)中,就系統(tǒng)而言,總共的虛存空間應(yīng)當(dāng)是 2^64Byte?
在該文章下面還有 Windows 64 位系統(tǒng)的虛存空間介紹,如下圖圖四所示。從圖中看到用戶虛存空間 8TB+系統(tǒng)空間 248TB=256TB=2^48 Byte ,這個數(shù)字似乎和上面所測得的單個進(jìn)程能夠申請到的最大虛存空間的數(shù)字有點接近了。
圖四
注意看圖四,還可以發(fā)現(xiàn) 64 位系統(tǒng)中還有很大很大的虛存空間保留沒有被使用的。從這個出發(fā)繼續(xù)查閱資料,然后找到了關(guān)于目前 64 位 CPU 的相關(guān)說明。由于目前還遠(yuǎn)遠(yuǎn)用不到 64 位那么大的空間,所以 AMD 64 位 CPU 目前只用了 48 位的尋址。而 Intel 的 64 位 CPU 是和 AMD 交叉授權(quán),所以 Intel 64CPU 也同樣只采用 48 位尋址。所以圖三的保留空間就得到了解釋。
再回到原先的問題,現(xiàn)在知道了就 64 位系統(tǒng)而言,虛擬內(nèi)存空間是可以達(dá)到 2^48Byte 那么大的,參考 Windows 64 位系統(tǒng)虛存空間結(jié)構(gòu),可以猜測Linux 64 位系統(tǒng)下,用戶虛存空間和系統(tǒng)內(nèi)核虛存空間分布和 Windows 是相似的,只是兩者大小比例有所差別。(因為找了很久,沒有找到Linux的官方文檔說明,只找到很舊的、32 位。所以不能提供準(zhǔn)確的參考,如果有讀者找到,希望可以告訴作者一下補(bǔ)上)。
不過,到現(xiàn)在,還有問題沒有解決,為什么所申請的虛存空間會比物理內(nèi)存與交換區(qū)的和大?
現(xiàn)在回到一開始沒有運(yùn)行完的程序,在終端 1 回車?yán)^續(xù)運(yùn)行程序,程序接著會對所申請到的第一個 100G 內(nèi)存塊每隔 2M 空間進(jìn)行寫操作,每回車一次,會寫 1000 次。回車幾次后,在終端 2 再執(zhí)行:
cat /proc/6674/status
得到下圖圖五:
圖五
由圖五可以看到正在使用的物理內(nèi)存 VmRSS 變小了,正在使用的交換區(qū)空間 VmSwap 迅速增大。但是兩者之和是在一直增加的,這就說明,申請到的虛擬內(nèi)存在未被使用之前,它只是一個數(shù)字,并沒有實際的物理內(nèi)存和交換區(qū)與之相對應(yīng)。當(dāng)對虛存進(jìn)行寫操作時,系統(tǒng)就會逐步分配物理內(nèi)存,而物理內(nèi)存的數(shù)據(jù)又會可能被系統(tǒng)調(diào)到交換區(qū)?,F(xiàn)在問題逐漸明了了。
如果我不停地對虛存空間進(jìn)行寫操作會怎樣,為了解決疑惑,在終端 1 不停回車,偶爾在終端 2 中查看 status 文件中的狀態(tài),寫到一定程度后,終端 1 出現(xiàn)了
[1] 7893 killed a.out
如圖六所示:
圖六
在進(jìn)程結(jié)束之前查看到的 status 文件顯示 VmRSS+VmSwap 約等 1.8G,加上系統(tǒng)占用和其他進(jìn)程占用,那么說此時物理內(nèi)存和交換區(qū)已經(jīng)接近極限了。再繼續(xù)運(yùn)行寫的時候,操作系統(tǒng)為了系統(tǒng)的正常運(yùn)行選擇把這個進(jìn)程殺死了。那么所有的疑問也解決了。
系統(tǒng)所允許的申請的虛存空間是可以超過物理內(nèi)存與交換區(qū)的和的。但是當(dāng)進(jìn)程所占用的物理內(nèi)存加上交換區(qū)影響到了系統(tǒng)的正常運(yùn)行就會被系統(tǒng)殺死。
編輯:hfy
-
Linux
+關(guān)注
關(guān)注
87文章
11207瀏覽量
208712 -
操作系統(tǒng)
+關(guān)注
關(guān)注
37文章
6684瀏覽量
123140 -
物理內(nèi)存
+關(guān)注
關(guān)注
0文章
11瀏覽量
8445 -
虛擬內(nèi)存
+關(guān)注
關(guān)注
0文章
70瀏覽量
8046
發(fā)布評論請先 登錄
相關(guān)推薦
評論