隨著電腦的發展,軟體應用程式的複雜性和資料量越來越大,對系統記憶體的要求也越來越高。身為Linux系統管理員,了解如何正確地管理和分配記憶體資源是必不可少的。本文將為你介紹Linux系統記憶體管理的基礎知識。
早期的程式都是直接運行在物理位址上,也就是說這個程式所需的空間不超過該機器的物理記憶體就不會有問題,但實際場景中都是多任務,多進程的,這種物理位址reserved給各個進程是不可靠的。
舉個栗子:假如有3個程式a,b,c,a需要10M,b需要100M,c需要20M,總記憶體就120M,按照之前的分配方式,前10M給a,10M-110M給b,系統還剩10M,但c需要20M,顯然剩下的記憶體是不夠c用的。怎麼辦?
為什麼要記憶體管理:
#1.效率問題
#可能你會想到當c程式跑的時候把b程式資料寫到磁碟上,等執行b的時候再資料從磁碟寫回來,先不說無法滿足b,c程式並行跑的需求,就連頻繁的io操作帶來的耗時問題也是無法接收的。
2.進程位址隔離問題
#除了效率問題,reserved給進程的空間如果需要被別的進程存取會崩潰。例如a進程存取的空間是前10M,但a程式中有一段程式碼存取10-110M的話就有可能導致b程式的崩潰,所以進程的位址空間需要彼此隔離。
3.重定位問題
#現實場景中不可能是單任務在分好的內存中運行,當多任務並行跑的情況下在動態申請釋放內存的時候有可能申請到其它進程裡的地址,這時候需要重定位到新的地址。
記憶體管理無非就是想辦法解決上面三個問題,如何提升記憶體的使用效率?如何使進程的位址空間隔離?如何解決程式運行時的重定位問題?
記憶體管理如何從虛擬位址對應到實體位址:
記憶體管理從虛擬位址對應到實體位址的過程也就是解決上面3個問題的過程。記憶體管理用分段機制和分頁機制分別解決了上面的3個問題,大概流程如下圖:
分段機制:
只要程式分了段,把整個段平移到任何位置後,段內的地址相對段基址是不變的,無論段基址是多少,只要給出段內偏移地址,cpu就能訪問到正確的指令。於是載入使用者程式時,只要將整個段的內容複製到新的位置,再將段基址暫存器中的位址改成該位址,程式便可準確地執行,因為程式中使用的是段內偏移位址,相對新的段基址,該偏移位址處的內容內容還是一樣的。
可以看出分段機制解決了進程間隔離和重定位的問題。這個動作是在硬體裡做的,但是有的硬體是沒有分段機制的,作為跨平台的linux就用了具有更通用性的分頁機制來解決線性地址到虛擬地址到物理地址的轉換。
分頁機制:
#可以參考《CPU是如何存取記憶體的? 》了解一級頁表的概念,linux為了相容32位元和64位,通常採用四級頁表,頁全域目錄,頁上級目錄,頁中間目錄,頁表:
這裡不詳細解釋linux是如何透過四級頁表來做線性位址(虛擬位址)到實體位址的轉換。
進程在切換的時候就是根據task_struct找到mm_struct裡的pgd字段,取得新進程的頁全域目錄,然後填入CR3暫存器,就完成了頁的切換。
動手看mmu分頁尋址的過程:
上程式碼:
#可以看出虛擬位址ffff99b488d48000對應的實體位址是80000000c8d48000。這個過程也是mmu的過程。
透過本文的介紹,我們了解了Linux系統記憶體管理的基礎知識,包括記憶體分區、虛擬記憶體、交換空間等內容。在實際的工作中,正確的記憶體管理可以提高系統的穩定性和效能,避免因記憶體問題而出現的意外故障。希望本文的介紹可以幫助你更好地理解Linux系統記憶體管理的原理與方法,讓你輕鬆應對各種記憶體管理問題。
以上是無需再擔心記憶體問題——Linux系統記憶體管理簡介的詳細內容。更多資訊請關注PHP中文網其他相關文章!