萬盛學電腦網

 萬盛學電腦網 >> Linux教程 >> 詳解Linux系統內存知識及調優方案

詳解Linux系統內存知識及調優方案

  內存是計算機中重要的部件之一,它是與CPU進行溝通的橋梁。計算機中所有程序的運行都是在內存中進行的,因此內存的性能對計算機的影響非常大。內存作用是用於暫時存放CPU中的運算數據,以及與硬盤等外部存儲器交換的數據。只要計算機在運行中,CPU就會把需要運算的數據調到內存中進行運算,當運算完成後CPU再將結果傳送出來,內存的運行也決定了計算機的穩定運行。對於整個操作系統來說,內存可能是最麻煩的的設備。而其性能的好壞直接影響著整個操作系統。

  我們知道CPU是不能與硬盤打交道的,只有數據被載入到內存中才可以被CPU調用。cpu在訪問內存的時候需要先像內存監控程序請求,由監控程序控制和分配內存的讀寫請求,這個監控程序叫做MMU(內存管理單元)。下面以32位系統來說明內存的訪問過程:

  32位的系統上每一個進程在訪問內存的時候,每一個進程都當做自己有4個G的內存空間可用,這叫虛擬內存(地址),虛擬內存轉化成物理內存是通過MMU來完成的。為了能夠從線性地址轉換成物理地址,需要page table(頁表)的內存空間,page table要載入到MMU上。為了完成線性地址到物理地址的映射,如果按照1個字節1個字節映射的話,需要一張非常大的表,這種轉換關系會非常的復雜。因此把內存空間又劃分成了另外一種存儲單元格式,通常為4K。在不同的硬件平台上,它們的大小一般是不一樣的,像x86 32位的有4k的頁;而64位的有4k頁,2M頁,4M頁,8M頁等等,默認都是4k的。每一個進程一般而言都有自己的頁路徑和頁表映射機制,不管那一個頁表都是由內核加載的。每一個進程只能看到自己的線性地址空間,想要增加新的內存的時候,只能在自己的線性地址空間中申請,並且申請後一定是通過操作系統的內核映射到物理地址空間中去找那麼一段空間,並且告訴線性地址空間准備好了,可以訪問,並且在page table中增加一條映射關系,於是就可以訪問物理內存了,這種叫做內存分配。但是新的申請一定是通過操作的內核到物理內存中去找那麼一段空間,並且告訴線性地址空間好了,可以建設映射關系,最終page table建立映射關系。

  這反映了上述描述過程的大體情況。可以看到每一個用戶程序都會有自己的頁表,並且映射到對應的主存儲器上去。

  根據上述文字和圖表的描述可以發現2個問題:

  1.每個進程如果需要訪問內存的時候都需要去查找page table的話,勢必會造成服務器的性能底下

  2.如果主存儲器的內存滿了以後,應用程序還需要調用內存的時候怎麼辦

  對於第一個問題,我們就需要借助TLB(Translation Lookaside Buffer)翻譯後備緩沖器。TLB是一個內存管理單元,它可以用於改進虛擬地址到物理地址轉換速度的緩存。這樣每次在查找page table的時候就可以先去TLB中查找相應的頁表數據,如果有就直接返回,沒有再去查找page table,並把查找到的結果緩存中TLB中。TLB雖然解決了緩存的功能,但是在那麼page table中查找映射關系仍然很慢,所以又有了page table的分級目錄。page table可以分為1級目錄,2級目錄和偏移量

  但是一個進程在運行的時候要頻繁的打開文件,關閉文件。這就意味著要頻繁的申請內存和釋放內存。有些能夠在內存中緩存數據的那些進程,他們對內存的分配和回收更多,那麼每一次分配都會在頁表中建立一個對應項。所以,就算內存的速度很快,大量頻繁的同一時間分配和釋放內存,依然會降低服務器的整體性能。當然內存空間不夠用的時候,我們稱為oom(out of memory,內存耗盡)。當內存耗盡的時候,,整個操作系統掛了。這種情況下我們可以考慮交換分區,交換分區畢竟是由硬盤虛擬出來的內存,所以其性能與真正的內存相比,差了很多,所以要盡力避免使用交換分區。有物理內存空間的時候盡量保證全部使用物理內存。cpu無論如何是不能給交換內存打交道的,它也只能給物理內存打交道,能尋址的空間也只能是物理內存。所以當真正物理內存空間不夠用的時候,會通過LRU算法把其中最近最少使用的內存放到交換內存中去,這樣物理內存中的那段空間就可以供新的程序使用了。但是這樣會引發另外的一個問題,即原來的進程通過page table尋找的時候,那一段空間的數據已經不屬於它了。所以此刻cpu發送通知或者異常告訴這個程序,這個地址空間已不屬於它,這個時候可能會出現2種情況:

  1.物理內存有可用的空間可用:這個時候cpu會根據以前的轉換策略會把交換分區中的那段內存重新送到物理內存中去,但是轉換過來的空間地址不一定會是以前的那一段空間地址,因為以前的那一段空間地址可能已經被別人使用了。

  2.物理內存沒有可用的空間可用:這個時候依然會使用LRU算發把當前物理地址空間上最近最少使用的空間地址轉換到交換內存中去,並把當前進程需要的這斷在交換空間中的內存送到物理內存空間中去,並且重新建立映射關系。

  上述通知或者異常出現的情況,通常叫做缺頁異常。缺頁異常也分為大異常和小異常兩種。大異常就是訪問的數據內存中沒有,不的不去硬盤上加載,無論是從交換內存中還是直接從磁盤的某個文件系統上,反正需要從硬盤上去加載,這種異常加載需要很長時間。小異常就是進程之間通過共享內存,第二個進程訪問的時候,查看本地的內存映射表沒有,但是其它進程已經擁有了這個內存頁,所以可以直接映射,這種異常加載需要的時間一般很短。

  在操作系統開機的時候,每一個io設備都會像cpu申請一些列的隨機端口,這種端口叫做io端口。在IBM PC體系結構中,I/O地址空間一共提供了65,536個8位的I/O端口。正是這些io端口的存在,cpu可以與io設備進行讀寫交互的過程。在執行讀寫操作時,CPU使用地址總線選擇所請求的I/O端口,使用數據總線在CPU寄存器和端口之間傳送數據。I/O端口還可以被映射到物理地址空間:因此,處理器和I/O設備之間的通信就可以直接使用對內存進行操作的匯編語言指令(例如,mov、and、or等等)。現代的硬件設備更傾向於映射I/O,因為這樣處理的速度較快,並可以和DMA結合起來使用。這樣io在和內存傳數據的時候就不需要通過cpu,cpu把總線的控制權交給DMA,每次io傳數據的時候就調用DMA一次,就把cpu給解放了出來。當數據傳輸完了以後,DMA通知給cpu中斷一次。DMA在運行的時候對整個總線有控制權限,當cpu發現有其它進程需要使用總線的時候,二者就會產生爭用。這個時候,在總線控制權的使用上,CPU和DMA具有相等的權限。只要CPU委托給了DMA,就不能隨意的收回這個委托,就要等待DMA的用完。

  如果沒有其它進程可以運行,或者其它進程運行的時間非常短,這個時候CPU發現我們的IO仍然沒有完成,那就意味著,CPU只能等待IO了。CPU在時間分配裡面有個iowait的值,就是CPU在等待IO花費的時間。有些是在同步調用過程中,CPU必須要等待IO的完成;否者CPU可以釋放IO的傳輸在背後自動完成,CPU自己去處理其它的事情。等硬盤數據傳輸完成以後,硬盤只需要像CPU發起一個通知即可。CPU外圍有一種設備,這個設備叫做可編程中斷控制器。每一個硬件設備為了給CPU通信,在剛開機的時候,在BIOS實現檢測的時候,這個設備就要到可編程中斷控制器上去注冊一個所謂的中斷號。那麼這個號碼就歸這個硬件使用了。當前主機上可能有多個硬件,每一個硬件都有自己的號碼,CPU在收到中斷號以後,就能夠通過中斷相量表查找到那個硬件設備進行中斷。並且就由對應的IO端口過來處理了。

  CPU正在運行其它進程,當一個中斷請求發過來的時候,CPU會立即終止當前正在處理的進程,而去處理中斷。當前CPU掛起當前正在處理的進程,轉而去執行中斷的過程,也叫做中斷切換。只不過,這種切換在量級別上比進程切換要低一些,而且任何中斷的優先級通常比任何進程也要高,因為我們指的是硬件中斷。中斷還分為上半部和下半部,一般而言,上半部就是CPU在處理的時候,把它接進來,放到內存中,如果這個事情不是特別緊急(CPU或者內核會自己判斷),因此在這種情況下,CPU回到現場繼續執行剛才掛起的進程,當這個進程處理完了,再回過頭來執行中斷的下半部分。

  在32位系統中,我們的內存(線性地址)地址空間中,一般而言,低地址空間有一個G是給內核使用的,上面3個G是給進程使用的。但是應該明白,其實在內核內存當中,再往下,不是直接這樣劃分的。32位系統和64位系統可能不一樣(物理地址),在32位系統中,最低端有那麼10多M的空間是給DMA使用的。DNA的總線寬度是很小的,可能只有幾位,所以尋址能力很有限,訪問的內存空間也就很有限。如果DMA需要復制數據,而且自己能夠尋址物理內存,還可以把數據直接壯哉進內存中去,那麼就必須保證DMA能夠尋址那段內存才行。尋址的前提就是把最低地址斷M,DA的尋址范圍內的那一段給了DMA。所以站在這個角度來說,我們的內存管理是分區域的。

  在32位系統上,16M的內存空間給了ZONE_DMA(DMA使用的物理地址空間);從16M到896M給了ZONE_NORMAL(正常物理地址空間),對於Linux操作系統來說,是內核可以直接訪問的地址空間;從896M到1G這斷空間叫做"Reserved"(預留的物理地址空間);從1G到4G的這段物理地址空間中,我們的內核是不能直接訪問的,要想訪問必須把其中的一段內容映射到Reserved來,在Reserved中保留出那一段內存的地址編碼,我們內核才能上去訪問,所以內核不直接訪問大於1G的物理地址空間。所以在32位系統上,它訪問內存當中的數據,中間是需要一個額外步驟的。

  在64位系統上,ZONE_DAM給了低端的1G地址空間,這個時候DMA的尋址能力被大大加強了;ZONE_DAM32可以使用4G的空間;而大於1G以上給劃分了ZONE_NORMAL,這段空間都可以被內核直接訪問。所以在64位上,內核訪問大於1G的內存地址,就不需要額外的步驟了,效率和性能上也大大增加,這也就是為什麼要使用64位系統的原因。

  在現在的PC架構上,AMD,INTER都支持一種機

copyright © 萬盛學電腦網 all rights reserved