亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 1207 | 回復: 0
打印 上一主題 下一主題

進程的線性地址空間的管理 [復制鏈接]

論壇徽章:
0
跳轉到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2008-05-02 13:50 |只看該作者 |倒序瀏覽
進程地址空間

首先明確兩個概念,頁和頁框。頁一般是在線性地址空間里的概念,頁既可以表示為4K的線性地址空間,也可以表示為存放在這個地址空間里面的數據(也就是對應的物理頁框里面存放的二進制數據單元);而頁框是在物理地址空間里的概念,一個頁框代表實際物理內存上面4K大小的存儲空間,可以想到硬件的分頁技術就是將頁框映射到頁的過程

  • linux為內核線程分配內存(頁框)的時候,毫不吝嗇,因為它十分信任內核線程,并且默認線程的內存分配的請求完全是正確的,并給予立即的響應,而且針對頁也沒有任何的保護措施。
  • linux在為用戶進程分配內存空間(頁框)的時候,異常小氣,它認為用戶進程對內存的請求是不緊迫的,它不信任用戶進程,并且隨時準備捕獲用戶進程引起的尋址錯誤,比方說:我們在程序里面用malloc動態(tài)申請了一段線性地址空間(獲得使用權),內核不會馬上就為這段線性地址映射物理地址空間(也就是分配實際的內存單元),它會等到你用戶真正用到這段地址的時候才會去分配實際的物理內存,具體過程是這樣的:用戶進程要訪問這段線性地址對應的物理地址,因為內核并沒有為其分配,用戶進程就會發(fā)生一個缺頁異常,告訴內核“內存中沒有我要訪問的數據,快點給我加載進來”,這個時候,內核知道自己的伎倆被識破,才開始懶洋洋的調用一個缺頁異常處理函數來對進程發(fā)送過來的缺頁進行處理。把硬盤上的數據加載到物理內存,再將相應的物理地址和線性地址建立好映射關系,哈哈,現在我們的用戶進程就又可以繼續(xù)執(zhí)行了。

什么情況下才會分配新的線性空間:
  1、執(zhí)行一個新的進程時,為進程分配線性空間
  2、在進程中exec一個程序,原來的線性地址會被釋放,為該進程分配一段新的線性空間(pid也不變)
  3、進程對一個文件進行了“內存映射”,這時會分配一段線性空間來映射這個文件的內容
  4、進程可能需要增加棧的空間,原來的?臻g用完,需要在分配一點空間給進程
  5、進程可能需要創(chuàng)建一個IPC共享線性區(qū)來與其他進程共享某些數據
  6、進程通過malloc來申請一段線性區(qū)來擴展自己的堆(brk()函數,具體自己去看)
什么時候發(fā)生無效線性地址?
  1、編程錯誤引發(fā)的無效線性地址引用
  2、缺頁異常引發(fā)的無效線性地址
目前為止我們大致了解了一下內核是怎么管理內存的,更加具體的還要看下面:linux-2.6.11
內核中使用的數據結構:

  • 內存描述符:mm_struct,用來描述進程的地址空間相關的信息,所有的mm_struct都放在一個雙向鏈表中
  • 線性區(qū):vm_area_struct,用來描述進程的一個線性區(qū)的描述符
  • 內存描述符和線性區(qū)的關系:線性區(qū)是用來描述進程所使用的一個線性區(qū)間的情況,包括線性空間的頭,尾和大小等,一個進程可能擁有多個線性區(qū),這些線性區(qū)用一個鏈表鏈接起來,并且線性地址升序排列;內存描述符其實就是這個鏈表的一個封裝體,不過它加了很多其他的信息,比如線性區(qū)個數,計數器,自旋鎖等(具體請查看相關書籍)
    線性區(qū)的組織方式有兩種:一個是鏈表,另一個是紅黑樹(這里不細說)

了解上面的概念之后,我們再來看看內核是怎么給進程增加和刪除線性區(qū)間的

  • 增加:一個進程的線性地址空間是由一個鏈表來表示的,鏈表的元素就是線性區(qū),每個線性區(qū)應該是有間隔的(如果相鄰內核會將其合并),那么增加一個線性區(qū)到進程的地址空間,內核檢查一個已經存在的線性區(qū)可不可以擴展,如果可以擴展,就對其進行擴展,比如有個線性區(qū)A大小為10,在其后面距離為100的地方還有一個線性區(qū)B大小為50,現在我想申請個70的空間,內核就看線性區(qū)A可不可以擴展,顯然線性區(qū)A后面還有100個單元的空間,可以擴展,因此對其擴展;如果我現在要申請個150的空間,顯然線性區(qū)A的擴展區(qū)是不能滿足他的要求的,他會繼續(xù)往后找,然后在擴展,如果實在找不到,就獨立在空閑的線性區(qū)間分配一個150的空間,將其鏈接到進程的線性區(qū)鏈表中。
  • 刪除:情況可以分為好幾種:將一整個線性區(qū)刪除:直接刪除,將線性區(qū)從鏈表上摘除,我沒看過相關刪除的代碼,感覺應該是這樣的:內核應該維持一個空閑線性地址空間的鏈表,摘除下來的線性區(qū)會被放到這個空閑鏈表中,不是簡單放入就可以的,還有對相鄰的線性區(qū)進行合并等,將線性區(qū)相關的標志位置上,表示這個線性區(qū)已經沒人用了
    只刪除線性區(qū)的一部分:刪除線性區(qū)的一部分還會分好幾種情況,刪除線性區(qū)頭部,刪除線性區(qū)的尾部,在線性區(qū)的中間進行刪除等,刪除的步驟應該和上面的大體相似。

缺頁異常處理:相當復雜,還是自己看書吧!

請求調頁:這里有個權衡的問題,一般進程請求頁框的分配有兩種處理方法:
1、直接給他分配頁框;
2、盡量推遲分配,即他真正需要的時候再分配,這里就需要臨時的調頁給進程。
考慮方法一:除非你有很大內存,要不然還是別用這種方法(盡管內核線程是這樣做的);考慮方法二:可以很好的節(jié)省內存的使用,但是臨時的調頁會浪費大量的CPU時間,這樣做劃算嗎?程序的局部性原理告訴我們,這樣做是劃算的,程序現在用到的地址在不久的將來用到的可能性是很大的,說明在某段時間內,程序只會訪問某段區(qū)域的內容,而不會訪問其他地址的內容,因此我們可以認為缺頁異常是“稀有時間”。
  
fork()方面的內容


  • fork大家都知道它是干什么。父進程創(chuàng)建一個子進程,拷貝父進程所有的代碼段,數據段,堆棧段,blablabla...好!現在給你個問題:如果子進程只是簡單的對復制過來的信息進行訪問,這樣做還劃算嗎?答案很顯然:不劃算。因為子進程根本就沒有對復制來的頁框進行修改,那我干什么還要去SB的復制?因此內核采用了COW技術,copy on write。子進程和父進程共享頁框,這些頁框被標記為只讀,當父進程或子進程要對某個頁框進行修改,就會觸發(fā)一個異常,內核會拷貝要修改的頁框拷貝到一個新的頁框并標記為可寫,當其他進程要對這個頁框進行寫時,內核會檢查這個進程是不是這個頁框的唯一宿主,若是,才能寫。



本文來自ChinaUnix博客,如果查看原文請點:http://blog.chinaunix.net/u2/64950/showart_654866.html
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復

  

北京盛拓優(yōu)訊信息技術有限公司. 版權所有 京ICP備16024965號-6 北京市公安局海淀分局網監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關心和支持過ChinaUnix的朋友們 轉載本站內容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP