Ⅰ linux進程虛擬地址空間的分布,以及堆和棧的區別
一、具體分布如圖所示:
二、關於堆和棧
(1)分配方式:
棧:由編譯器自動分配釋放,存放函數的參數回值,局部變數的值等。其操作方式類似於數據結構中的棧。
堆: 一般由程序員分配釋放,它的分配方式類似於鏈表。
(2)申請後系統的響應:
棧:只要所申請的空間小於棧的剩餘空間,則系統為程序分配內存,否則棧溢出。
堆:操作系統有一個記錄空閑內存地址的鏈表,當系統收到程序的申請時,遍歷該鏈表,找出第一個大於所申請空間的節點,然後將其從鏈表中刪除並分配,如果沒用完,則系統會把多餘的重新放回到鏈表中。
(3)申請大小的限制:
棧:棧答是高地址向低地址擴展的連續內存,棧的大小一般是2M;
堆:堆是低地址向高地址擴展的不連續內存,堆的大小與計算機有效的虛擬內存有關系。
(4)申請效率:
棧:由系統自動分配,速度較快;
堆:速度慢,容易產生內存碎片;
關於Linux命令的介紹,看看《linux就該這么學》,具體關於這一章地址3w(dot)linuxprobe/chapter-02(dot)html.
Ⅱ 為什麼linux操作系統內核在虛擬地址空間的3GB處
1: 並不是所有平台都抄在3G
2:i386沒有PAE,並且編譯時沒有特別指定的時候才在3G
3:在這種情況下,由於地址匯流排最大隻能訪問4G的空間,並且為了在切換入內核空間時不需要重新載入內核的頁表,使用了一個技巧:讓內核與用戶空間影射到同一內存段。根據實際需要,給內核保留了1G的內存空間,並且為了讓應用程序看起來是從0地址開始的,那麼內核的1G內存段就佔用了3G~4G的空間。這就回答了你的問題。
4:其實這種方法不是唯一的,比如,可以讓內核少佔用一些空間,那麼就不是3G了。或者,讓內核與應用程序不映射到同一個內存空間,那麼用戶程序可以使用幾乎全部的4G空間(有些patch可以做到,但這樣的話內核<->用戶態切換時代價很大。說幾乎4G的原因是:調用syscall時還是需要一段內存傳遞參數的)。
Ⅲ Linux中4G的虛擬地址空間 最少需要多大的物理地址來映射
4G=4096M。一頁目錄表1024項,一個目錄項4M。一頁頁表4M,一個頁表項4K。
Ⅳ 【深入淺出Linux】關於mmap的解析
看這篇文章之前需要知道一個概念
虛擬內存系統通過將虛擬內存分割為稱作虛擬頁(Virtual Page,VP)大小固定的塊,一般情況下,每個虛擬頁的大小默認是4096位元組。同樣的,物理內存也被分割為物理頁(Physical Page,PP),也為4096位元組。
在LINUX中我們可以使用mmap用來在進程虛擬內存地址空間中分配地址空間,創建和物理內存的映射關系。
映射關系可以分為兩種
1、文件映射
磁碟文件映射進程的虛擬地址空間,使用文件內容初始化物理內存。
2、匿名映射
初始化全為0的內存空間。
而對於映射關系是否共享又分為
1、私有映射(MAP_PRIVATE)
多進程間數據共享,修改不反應到磁碟實際文件,是一個-on-write(寫時復制)的映射方式。
2、共享映射(MAP_SHARED)
多進程間數據共享,修改反應到磁碟實際文件中。
因此總結起來有4種組合
1、私有文件映射
多個進程使用同樣的物理內存頁進行初始化,但是各個進程對內存文件的修改不會共享,也不會反應到物理文件中
2、私有匿名映射
mmap會創建一個新的映射,各個進程不共享,這種使用主要用於分配內存(malloc分配大內存會調用mmap)。
例如開辟新進程時,會為每個進程分配虛擬的地址空間,這些虛擬地址映射的物理內存空間各個進程間讀的時候共享,寫的時候會-on-write。
3、共享文件映射
多個進程通過虛擬內存技術共享同樣的物理內存空間,對內存文件 的修改會反應到實際物理文件中,他也是進程間通信(IPC)的一種機制。
4、共享匿名映射
這種機制在進行fork的時候不會採用寫時復制,父子進程完全共享同樣的物理內存頁,這也就實現了父子進程通信(IPC).
這里值得注意的是,mmap只是在虛擬內存分配了地址空間,只有在第一次訪問虛擬內存的時候才分配物理內存。
在mmap之後,並沒有在將文件內容載入到物理頁上,只上在虛擬內存中分配了地址空間。當進程在訪問這段地址時,通過查找頁表,發現虛擬內存對應的頁沒有在物理內存中緩存,則產生"缺頁",由內核的缺頁異常處理程序處理,將文件對應內容,以頁為單位(4096)載入到物理內存,注意是只載入缺頁,但也會受操作系統一些調度策略影響,載入的比所需的多。
1.write
因為物理內存是有限的,mmap在寫入數據超過物理內存時,操作系統會進行頁置換,根據淘汰演算法,將需要淘汰的頁置換成所需的新頁,所以mmap對應的內存是可以被淘汰的(若內存頁是"臟"的,則操作系統會先將數據回寫磁碟再淘汰)。這樣,就算mmap的數據遠大於物理內存,操作系統也能很好地處理,不會產生功能上的問題。
2.read
從圖中可以看出,mmap要比普通的read系統調用少了一次的過程。因為read調用,進程是無法直接訪問kernel space的,所以在read系統調用返回前,內核需要將數據從內核復制到進程指定的buffer。但mmap之後,進程可以直接訪問mmap的數據(page cache)。
測試結果來源於: 深入剖析mmap-從三個關鍵問題說起
1.讀性能分析
場景:對2G的文件進行順序寫入
可以看到mmap在100byte寫入時已經基本達到最大寫入性能,而write調用需要在4096(也就是一個page size)時,才能達到最大寫入性能。
從測試結果可以看出,在寫小數據時,mmap會比write調用快,但在寫大數據時,反而沒那麼快。
2.寫性能分析
場景:對2G的文件進行順序讀取(為了避免磁碟對測試的影響,2G文件都緩存在pagecache中)
由上可以看出,在read上面,mmap的性能還是非常好的。
優點如下:
1、對文件的讀取操作跨過了頁緩存,減少了數據的拷貝次數,用內存讀寫取代I/O讀寫,提高了文件讀取效率。
2、實現了用戶空間和內核空間的高效交互方式。兩空間的各自修改操作可以直接反映在映射的區域內,從而被對方空間及時捕捉。
3、提供進程間共享內存及相互通信的方式。不管是父子進程還是無親緣關系的進程,都可以將自身用戶空間映射到同一個文件或匿名映射到同一片區域。從而通過各自對映射區域的改動,達到進程間通信和進程間共享的目的。同時,如果進程A和進程B都映射了區域C,當A第一次讀取C時通過缺頁從磁碟復制文件頁到內存中;但當B再讀C的相同頁面時,雖然也會產生缺頁異常,但是不再需要從磁碟中復制文件過來,而可直接使用已經保存在內存中的文件數據。
4、可用於實現高效的大規模數據傳輸。內存空間不足,是制約大數據操作的一個方面,解決方案往往是藉助硬碟空間協助操作,補充內存的不足。但是進一步會造成大量的文件I/O操作,極大影響效率。這個問題可以通過mmap映射很好的解決。換句話說,但凡是需要用磁碟空間代替內存的時候,mmap都可以發揮其功效。
缺點如下:
1.文件如果很小,是小於4096位元組的,比如10位元組,由於內存的最小粒度是頁,而進程虛擬地址空間和內存的映射也是以頁為單位。雖然被映射的文件只有10位元組,但是對應到進程虛擬地址區域的大小需要滿足整頁大小,因此mmap函數執行後,實際映射到虛擬內存區域的是4096個位元組,11~4096的位元組部分用零填充。因此如果連續mmap小文件,會浪費內存空間。
3.如果更新文件的操作很多,會觸發大量的臟頁回寫及由此引發的隨機IO上。所以在隨機寫很多的情況下,mmap方式在效率上不一定會比帶緩沖區的一般寫快。
Ⅳ linux下32位虛擬地址空間是多少
64位的linux採用復4級頁表,支持制的最大物理內存為64T。 對於虛擬地址空間的劃分,將0x0000,0000,0000,0000 – 0x0000,7fff,ffff,f000這128T地址用於用戶空間;而0xffff,8000,0000,0000以上的128T為系統空間地址。 具體的不是一兩句能說清楚了。
Ⅵ 64位的linux上單個進程可以使用的最大內存數量是多少
對於64位Linux允許多達128個TB單個進程的虛擬地址空間,並且能夠解決大約64 TB的物理存儲器,但版是受處理器和系權統的限制。原話:64-bit Linux allows up to 128 TB of virtual address space for indivial processes, and can address approximately 64 TB of physical memory, subject to processor and system limitations.只要你的機器有足夠的內存統統可以給你放倒。連銀河曙光都能放下你的機器肯定不在話下:)而理論值更高,一個64位的微處理器可定址存儲器16 EB(1TB=1024GB,1PB=1024TB,1EB=1024PB自己換算)。順便說一下64位的windows企業伺服器最大2TB內存。