不是僅僅 Linux 是這麼設計的,整個現代流行的作業系統都是這麼設計的。
應用程式被讀入記憶體後,為了保證系統的統一性,所有的程式都有同樣的一套定址規範。這個定址就是虛擬地址。這個虛擬地址是系統提供轉換的,不是程式的工作。
如果系統不提供這個功能,那麼應用程式就需要自己去尋找沒有被使用的記憶體,以及還要自己去處理記憶體容量的問題,而且如果程式呼叫外部的一些函式庫,這些函式庫也需要分配記憶體,這會導致應用程式的設計難度非常大,每個應用程式實際上就是一個作業系統了。多個程式共同執行導致記憶體使用混亂也很容易出現。
應用程式申請記憶體,使用的是作業系統的記憶體分配功能。這樣作業系統可以根據實際情況給應用程式記憶體,程式不需要考慮因為記憶體位置不同而必須不同編寫的難度。而且作業系統還可以提供虛擬記憶體等等各種方式來擴充記憶體,這樣的記憶體對於應用程式來說是不需要考慮的,一切都有系統打理。
使用虛擬地址後,對於應用程式來說,他的記憶體使用不需要考慮其他的程式佔用,也不需要考慮記憶體容量的問題,也不需要考慮記憶體塊位置,函式庫的呼叫也都扔給作業系統打理。這使得應用程式不需要考慮具體如何管理記憶體,只需要考慮作為應用程式的應用部分。
而且,因為記憶體是虛擬的,應用程式一些函式呼叫,作業系統可以把多個應用程式的呼叫都用同一套資料來處理,這樣,既可以節約記憶體使用(就是啟動100個應用程式,也只需要記憶體裡有一套函式庫而已),也可以做到外部函式庫和應用程式沒有直接關聯,純粹是由系統做虛擬地址過渡。
至於為什麼 4G ,這是傳統+一些相容的考慮。
以前沒有這個技術時,每個程式都可以完全使用整個系統,整個空間是連續的。到了這種虛擬地址的方式後,每個程式還是有自己“獨立”的一整套記憶體地址。但每個程式記憶體使用量肯定不一樣。那麼多少記憶體空間才完全夠用呢?當時因為正好使用了 32 位系統。那麼就把整個 32 位環境支援的 4G 記憶體容量作為這個極限。
不過因為記憶體地址是虛擬的。實際應用程式要用記憶體,是需要先申請的,所以只有程式申請後,真實記憶體才會被佔用。這個 4G 只是在演算法上作為極限。
不過因為 4G 也是硬體極限。所以 4G 以外的地址都是不能使用的,這就導致另一個問題,一些硬體有儲存器,有些硬體需要儲存空間做互動(比如 PCI ,比如各種硬體,比如 AGP 顯示卡)。這些儲存區域怎麼處理?
所以,Windows Vista 的 32 位版在 4G 記憶體的機器上曾經報出只有 3.5G (有的機器甚至只有 3.25G 可以用)。就是這個問題的解決辦法導致的:把硬體的記憶體用虛擬地址的方式,放到虛擬地址的最後面。這樣應用程式呼叫硬體儲存時,可以直接按照記憶體的方式讀寫。這樣應用程式就很好的統一了儲存介面:只有 4G 的記憶體範圍,不存在其他方式的儲存呼叫方式(硬碟需要用讀寫功能讀取到記憶體後才能處理,而不是直接進行處理)。這樣應用程式的開發就很簡單,而且整個記憶體的使用每個程式都一樣。不存在各種硬體的原因而不同導致的需要重新設計記憶體管理演算法。作業系統也能根據實際應用程式的需要隨時分配資料,也可以根據每個程式的執行情況,區別的提供物理記憶體或者虛擬的記憶體。
這麼設計最大的一個好處是,硬體環境和應用程式是無關的,中間由作業系統做轉換。而且應用程式互相之間也沒有影響,就好象整個記憶體都由他自己一個程式使用一樣。
PS:說了半天,我發現我自己也說不清楚其中的緣由……
不是僅僅 Linux 是這麼設計的,整個現代流行的作業系統都是這麼設計的。
應用程式被讀入記憶體後,為了保證系統的統一性,所有的程式都有同樣的一套定址規範。這個定址就是虛擬地址。這個虛擬地址是系統提供轉換的,不是程式的工作。
如果系統不提供這個功能,那麼應用程式就需要自己去尋找沒有被使用的記憶體,以及還要自己去處理記憶體容量的問題,而且如果程式呼叫外部的一些函式庫,這些函式庫也需要分配記憶體,這會導致應用程式的設計難度非常大,每個應用程式實際上就是一個作業系統了。多個程式共同執行導致記憶體使用混亂也很容易出現。
應用程式申請記憶體,使用的是作業系統的記憶體分配功能。這樣作業系統可以根據實際情況給應用程式記憶體,程式不需要考慮因為記憶體位置不同而必須不同編寫的難度。而且作業系統還可以提供虛擬記憶體等等各種方式來擴充記憶體,這樣的記憶體對於應用程式來說是不需要考慮的,一切都有系統打理。
使用虛擬地址後,對於應用程式來說,他的記憶體使用不需要考慮其他的程式佔用,也不需要考慮記憶體容量的問題,也不需要考慮記憶體塊位置,函式庫的呼叫也都扔給作業系統打理。這使得應用程式不需要考慮具體如何管理記憶體,只需要考慮作為應用程式的應用部分。
而且,因為記憶體是虛擬的,應用程式一些函式呼叫,作業系統可以把多個應用程式的呼叫都用同一套資料來處理,這樣,既可以節約記憶體使用(就是啟動100個應用程式,也只需要記憶體裡有一套函式庫而已),也可以做到外部函式庫和應用程式沒有直接關聯,純粹是由系統做虛擬地址過渡。
至於為什麼 4G ,這是傳統+一些相容的考慮。
以前沒有這個技術時,每個程式都可以完全使用整個系統,整個空間是連續的。到了這種虛擬地址的方式後,每個程式還是有自己“獨立”的一整套記憶體地址。但每個程式記憶體使用量肯定不一樣。那麼多少記憶體空間才完全夠用呢?當時因為正好使用了 32 位系統。那麼就把整個 32 位環境支援的 4G 記憶體容量作為這個極限。
不過因為記憶體地址是虛擬的。實際應用程式要用記憶體,是需要先申請的,所以只有程式申請後,真實記憶體才會被佔用。這個 4G 只是在演算法上作為極限。
不過因為 4G 也是硬體極限。所以 4G 以外的地址都是不能使用的,這就導致另一個問題,一些硬體有儲存器,有些硬體需要儲存空間做互動(比如 PCI ,比如各種硬體,比如 AGP 顯示卡)。這些儲存區域怎麼處理?
所以,Windows Vista 的 32 位版在 4G 記憶體的機器上曾經報出只有 3.5G (有的機器甚至只有 3.25G 可以用)。就是這個問題的解決辦法導致的:把硬體的記憶體用虛擬地址的方式,放到虛擬地址的最後面。這樣應用程式呼叫硬體儲存時,可以直接按照記憶體的方式讀寫。這樣應用程式就很好的統一了儲存介面:只有 4G 的記憶體範圍,不存在其他方式的儲存呼叫方式(硬碟需要用讀寫功能讀取到記憶體後才能處理,而不是直接進行處理)。這樣應用程式的開發就很簡單,而且整個記憶體的使用每個程式都一樣。不存在各種硬體的原因而不同導致的需要重新設計記憶體管理演算法。作業系統也能根據實際應用程式的需要隨時分配資料,也可以根據每個程式的執行情況,區別的提供物理記憶體或者虛擬的記憶體。
這麼設計最大的一個好處是,硬體環境和應用程式是無關的,中間由作業系統做轉換。而且應用程式互相之間也沒有影響,就好象整個記憶體都由他自己一個程式使用一樣。
PS:說了半天,我發現我自己也說不清楚其中的緣由……