理解內存管理中的分段和分頁(轉)


作者:匿名用戶
鏈接:https://www.zhihu.com/question/50796850/answer/522734117
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

要理解分段和分頁,那么得理解為什么會出現分段和分頁的技術

首先,這兩個技術都是為了利用和管理好計算機的資源--內存

在分段這個技術還沒有出現之前,程序運行是需要從內存中分配出足夠多的連續的內存,然后把整個程序裝載進去。舉個例子,某個程序大小是10M,然后,就需要有連續的10M內存空間才能把這個程序裝載到內存里面。如果無法找到連續的10M內存,就無法把這個程序裝載進內存里面,程序也就無法得到運行。

上面這種直接把整個程序裝載進內存的方式是有一定的問題的。例如:

1、地址空間不隔離

如何理解地址空間不隔離?

舉個例子,假設我有兩個程序,一個是程序A,一個是程序B。程序A在內存中的地址假設是0x00000000~0x00000099,程序B在內存中的地址假設是0x00000100~x00000199。那么假設你在程序A中,本來想操作地址0x00000050,不小心手殘操作了地址0x00000150,那么,不好的事情或許會發生。你影響了程序A也就罷了,你把程序B也搞了一頓。

2、程序運行時候的地址不確定

如何理解程序運行時候的地址不確定?

因為我們程序每次要運行的時候,都是需要裝載到內存中的,假設你在程序中寫死了要操作某個地址的內存,例如你要地址0x00000010。但是問題來了,你能夠保證你操作的地址0x00000010真的就是你原來想操作的那個位置嗎?很可能程序第一次裝載進內存的位置是0x00000000~0x00000099,而程序第二次運行的時候,這個程序裝載進內存的位置變成了0x00000200~0x00000299,而你操作的0x00000010地址壓根就不是屬於這個程序所占有的內存。

3、內存使用率低下

如何理解內存使用率低下呢?

舉個例子,假設你寫了3個程序,其中程序A大小為10M,程序B為70M,程序C的大小為30M你的計算機的內存總共有100M。

這三個程序加起來有110M,顯然這三個程序是無法同時存在於內存中的。

並且最多只能夠同時運行兩個程序。可能是這樣的,程序A占有的內存空間是0x00000000~0x00000009,程序B占有的內存空間是0x00000010~0x00000079。假設這個時候程序C要運行該怎么做?可以把其中的一個程序換出到磁盤上,然后再把程序C裝載到內存中。假設是把程序A換出,那么程序C還是無法裝載進內存中,因為內存中空閑的連續區域有兩塊,一塊是原來程序A占有的那10M,還有就是從0x00000080~0x00000099這20M,所以,30M的程序C無法裝載進內存中。那么,唯一的辦法就是把程序B換出,保留程序A,但是,此時會有60M的內存無法利用起來,很浪費對吧。

然后,人們就去尋求一種辦法來解決這些問題。

有一句話說的好:計算機科學領域的任何問題都可以通過增加一個間接的中間層來解決。

(這種思想在現在也用的很廣泛,例如很多優秀的中間層:Nginx、Redis等等)

所以,分段這種技術就出現了。

為了實現分段的這個技術,需要引入虛擬地址空間的概念。那么什么是地址空間呢?簡單的說就是可以尋址的一片空間。如果這個空間是虛擬的,我們就叫做虛擬地址空間;如果這個空間是真實存在的,我們就叫做物理地址空間。虛擬地址空間是可以任意的大的,因為是虛擬的。而物理地址空間是真實存在的,所以是有限的。

然后,分段這個技術做了一件什么事情呢?

把虛擬地址空間映射到了物理地址空間,並且你寫的程序操作的是虛擬地址。假設,程序A的虛擬地址空間是0x00000100~0x00000200。此時,不僅需要一塊連續的物理內存來存放程序A,還需要把程序A的虛擬地址空間映射到(轉換為)物理地址空間。可能,程序A的虛擬地址空間從0x00000100~0x00000200映射到了物理地址空間0x00000000~0x00000100。

那么分段的技術可以解決什么問題呢?可以解決上面1、2兩個問題。

在問題1中,假設程序A的虛擬地址空間是0x00000000~0x00000099,映射到的物理地址空間是0x00000600~0x00000699,程序B的虛擬地址空間是0x00000100~0x00000199,映射到的物理地址空間是0x00000300~0x00000399。假設你還是手殘,在程序A中操作了地址0x00000150,但是英文此時的地址0x00000150是虛擬的,而虛擬化的操作是在操作系統的掌控中的,所以,操作系統有能力判斷,這個虛擬地址0x00000150是有問題的,然后阻止后續的操作。所以,體現出了隔離性。(另一種體現隔離性的方式就是,操作同一個虛擬地址,實際上可能操作的是不同的物理地址)

(注意,實際上,很可能程序A和程序B的虛擬地址都是0x00000000~0x00000099。這里的舉例只是為了方便理解。)

問題2也很好的解決了。正是因為這種映射,使得程序無需關注物理地址是多少,只要虛擬地址沒有改變,那么,程序就不會操作地址不當。

但是問題3仍然沒有解決

因為第三個問題是換入換出的問題,這個問題的關鍵是能不能在換出一個完整的程序之后,把另一個完整的程序換進來。而這種分段機制,映射的是一片連續的物理內存,所以問題3得不到解決。

而問題出在哪呢?就是完整和連續

而分頁技術的出現就是為了解決這個問題的。分頁這個技術仍然是一種虛擬地址空間到物理地址空間映射的機制。但是,粒度更加的小了。單位不是整個程序,而是某個“頁”,一段虛擬地址空間組成的某一頁映射到一段物理地址空間組成的某一頁。(如何理解這個“頁”的概念,這個問題下的其他同學回答過)

分頁這個技術,它的虛擬地址空間仍然是連續的,但是,每一頁映射后的物理地址就不一定是連續的了。正是因為有了分頁的概念,程序的換入換出就可以以頁為單位了。那么,為什么就可以只換出某一頁呢?實際上,不是為什么可以換出某一頁,而是可以換出CPU還用不到的那些程序代碼、數據。但是,把這些都換出到磁盤,萬一下次CPU就要使用這些代碼和數據怎么辦?又得把這些代碼、數據裝載進內存。性能有影響對吧。所以,我們把換入換出的單位變小,變成了“頁”。(實際上,這利用了空間局部性)

所以,同學們想想,問題3是不是就解決了呢?

所以,分段和分頁的區別在於:粒度

 
轉自:怎樣通俗的理解操作系統中內存管理分頁和分段? - 知乎 https://www.zhihu.com/question/50796850/answer/522734117


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM