apache 微软 linux java nginx mysql google Python Android Firefox centos Ubuntu 编程 开源 shell wordpress 程序员 php 云计算 Windows

Linux应用程序变成之内存管理和使用

  Linux內核使用頁式內存管理,應用程序給出的內存地址是虛擬地址,它需要經過若幹級頁表一級一級的變換,才變成真正的物理地址。
  想一下,地址映射還是一件很恐怖的事情。當訪問一個由虛擬地址表示的內存空間時,需要先經過若幹次的內存訪問,得到每一級頁表中用於轉換的頁表項(頁表是存放在內存裏面的),才能完成映射。也就是說,要實現一次內存訪問,實際上內存被訪問了N+1次(N=頁表級數),並且還需要做N次加法運算。
 所以,地址映射必須要有硬件支持,mmu(內存管理單元)就是這個硬件。並且需要有cache來保存頁表,這個cache就是TLB(Translation lookaside buffer)。
 盡管如此,地址映射還是有著不小的開銷。假設cache的訪存速度是內存的10倍,命中率是40%,頁表有三級,那麽平均一次虛擬地址訪問大概就消耗了兩次物理內存訪問的時間。
 於是,一些嵌入式硬件上可能會放棄使用mmu,這樣的硬件能夠運行VxWorks(一個很高效的嵌入式實時操作系統)、linux(linux也有禁用mmu的編譯選項)、等系統。
 但是使用mmu的優勢也是很大的,最主要的是出於安全性考慮。各個進程都是相互獨立的虛擬地址空間,互不幹擾。而放棄地址映射之後,所有程序將運行在同一個地址空間。於是,在沒有mmu的機器上,一個進程越界訪存,可能引起其他進程莫名其妙的錯誤,甚至導致內核崩潰。
 在地址映射這個問題上,內核只提供頁表,實際的轉換是由硬件去完成的。那麽內核如何生成這些頁表呢?這就有兩方面的內容,虛擬地址空間的管理和物理內存的管理。(實際上只有用戶態的地址映射才需要管理,內核態的地址映射是寫死的。

延伸阅读

评论