python資料處理——bsonId與時間戳的相互轉換
作業系統為每一個程序分配一套虛擬地址。程序與程序之間隔離開來,互不干涉。
作業系統會提供一種機制,將不同程序的虛擬地址和不同記憶體的實體地址對映起來。
作業系統是如何管理虛擬地址和實體地址之間的關係?
- 記憶體分段
- 記憶體分頁
記憶體分段
程式是由若干邏輯分段組成的,如可由程式碼分段,資料分段,棧段,堆段組成,不同的段是具有不同的屬性,所以就用分段的形式把這些段分離出來。
虛擬地址是通過段表與實體記憶體進行對映,分段機制會把程式的虛擬地址分為4個段,每個段在段表中有意向,再這一項找到段的基地址,再加上偏移量,於是就能找到實體記憶體中的地址。
分段的不足之處
記憶體碎片
外部記憶體碎片,也就是產生了多個不連續的小實體記憶體,導致新的程式無法被裝載。
- 解決外部記憶體碎片的問題就是記憶體交換
例如,可以把音樂程式佔用的256MB記憶體寫到硬碟上,然後再從硬碟讀回到記憶體裡。不過再讀回的時候,我們不能裝載到原來的位置,而是僅僅跟著那已經佔用的512MB記憶體後面,這樣就能空缺出連續的256MB空間,於是新的200MB 程式就可以裝載進來
這個記憶體交換空間在linux 系統中,也就是我們常看到的Swap 空間,這塊空間是從硬碟劃分出來的,用於記憶體和硬碟的空間交換。
內部記憶體碎片,程式所有的記憶體都被裝在到實體記憶體中,但是這個程式有部分的記憶體可能不是經常使用,這也會導致記憶體的浪費
記憶體交換效率低下
因為硬碟的訪問速度比記憶體慢太多了,每一次記憶體交換,我們都需要把一大段連續的記憶體資料寫到硬碟上。
為了解決記憶體碎片和記憶體交換效率低的問題就出現了記憶體分頁
記憶體分頁
分段的好處是能產生連續的記憶體空間,但是會出現記憶體碎片和記憶體交換的空間太多的問題。
要解決這個問題就要想出能少出現一些記憶體碎片的辦法,另外當需要進行記憶體交換的時候,讓需要交換寫入或者從磁碟裝載的資料更少一些,這樣就可以解決問題,這個辦法就是記憶體分頁。
分頁是把整個虛擬和實體記憶體空間切成一段段固定尺寸的大小,這樣一個連續且尺寸固定的記憶體空間,稱為“頁”, 在LINUX 下每一個頁的大小為4KB
頁表是儲存在記憶體裡面,記憶體管理單元(MMU)就做將虛擬記憶體地址轉換為實體地址的工作
當程序訪問的虛擬地址在頁表中查詢不到時候,系統就會產生一個缺頁異常,進入系統核心空間分配實體記憶體、更新程序頁表、最後再返回使用者空間,恢復程序的執行。
分頁是如何解決分段的記憶體碎片和記憶體交換效率低的問題?
由於記憶體空間是預先劃分好的,也就不會像分段會產生間隙非常小的記憶體,這正是分段會產生記憶體碎片的原因,而採用了分頁,那麼釋放記憶體都是以頁為單位釋放的,也就不會產生無法給程序使用的小記憶體。
由於記憶體空間的不足,作業系統會把其他正在執行的程序中的“最近沒被使用”的記憶體頁面給釋放掉,也就是暫時寫在硬碟上,稱為換出(swap out)。 一旦需要的時候,再載入進來,稱為換入。所以,一次性寫入磁碟的頁只有少數的一個頁或者幾個頁,不會花太多時間,記憶體交換的效率就相對比較高。
更進一步地,分頁的方式使得我們在載入程式的時候,不在需要一次性的都把程式載入到實體記憶體中,我們完全可以再進行虛擬記憶體和實體記憶體的頁之間的對映之後,並不真的把頁載入到實體記憶體去,而是隻有在程式執行中,需要用到對應虛擬記憶體裡面的指令和資料時,再載入到實體記憶體裡面去。