linux內存管理內核
1. linux進程內存如何管理
Linux系統提供了復雜的存儲管理系統,使得進程所能訪問的內存達到4GB。在Linux系統中,進程的4GB內存空間被分為兩個部分——用戶空間與內核空間。用戶空間的地址一般分布為0~3GB(即PAGE_OFFSET,在Ox86中它等於OxC0000000),這樣,剩下的3~4GB為內核空間,用戶進程通常只能訪問用戶空間的虛擬地址,不能訪問內核空間的虛擬地址。用戶進程只有通過系統調用(代表用戶進程在內核態執行)等方式才可以訪問到內核空間。每個進程的用戶空間都是完全獨立、互不相乾的,用戶進程各自有不同的頁表。而內核空間是由內核負責映射,它並不會跟著進程改變,是固定的。內核空間的虛擬地址到物理地址映射是被所有進程共享的,內核的虛擬空間獨立於其他程序。
Linux中1GB的內核地址空間又被劃分為物理內存映射區、虛擬內存分配區、高端頁面映射區、專用頁面映射區和系統保留映射區這幾個區域。對於x86系統而言,一般情況下,物理內存映射區最大長度為896MB,系統的物理內存被順序映射在內核空間的這個區域中。當系統物理內存大於896MB時,超過物理內存映射區的那部分內存稱為高端內存(而未超過物理內存映射區的內存通常被稱為常規內存),內核在存取高端內存時必須將它們映射到高端頁面映射區。Linux保留內核空間最頂部FIXADDR_TOP~4GB的區域作為保留區。當系統物理內存超過4GB時,必須使用CPU的擴展分頁(PAE)模式所提供的64位頁目錄項才能存取到4GB以上的物理內存,這需要CPU的支持。加入了PAE功能的Intel Pentium Pro及以後的CPU允許內存最大可配置到64GB,它們具備36位物理地址空間定址能力。
由此可見,對於32位的x86而言,在3~4GB之間的內核空間中,從低地址到高地址依次為:物理內存映射區→隔離帶→vmalloc虛擬內存分配器區→隔離帶→高端內存映射區→專用頁面映射區→保留區。
2. linux內存管理--linux內核高端內存
linux內核地址映射模型
x86
CPU採用了段頁式地址映射模型。進程代碼中的地址為邏輯地址,經過段頁式地址映射後,才真正訪問物理內存。
段頁式機制如下圖。
linux內核地址空間劃分
通常32位linux內核地址空間劃分0~3G為用戶空間,3~4G為內核空間。注意這里是32位內核地址空間劃分,64位內核地址空間劃分是不同的。
linux內核高端內存的由來
當內核模塊代碼或線程訪問內存時,代碼中的內存地址都為邏輯地址,而對應到真正的物理內存地址,需要地址一對一的映射,如邏輯地址0xc0000003對應的物理地址為0×3,0xc0000004對應的物理地址為0×4,…
…,邏輯地址與物理地址對應的關系為
物理地址
=
邏輯地址
0xC0000000
邏輯地址物理內存地址0xc00000000×00xc00000010×10xc00000020×20xc00000030×3…
…
0xe00000000×20000000……0xffffffff0×40000000
??
顯然不能將內核地址空間0xc0000000
~
0xfffffff全部用來簡單的地址映射。因此x86架構中將內核地址空間劃分三部分:ZONE_DMA、ZONE_NORMAL和ZONE_HIGHMEM。ZONE_HIGHMEM即為高端內存,這就是內存高端內存概念的由來。
在x86結構中,三種類型的區域如下:
ZONE_DMA
內存開始的16MB
ZONE_NORMAL
16MB~896MB
ZONE_HIGHMEM
896MB
~
結束
linux內核高端內存的理解
前面我們解釋了高端內存的由來。
linux將內核地址空間劃分為三部分ZONE_DMA、ZONE_NORMAL和ZONE_HIGHMEM,高端內存HIGH_MEM地址空間范圍為0xF8000000
~
0xFFFFFFFF(896MB~1024MB)。那麼如內核是如何藉助128MB高端內存地址空間是如何實現訪問可以所有物理內存?
當內核想訪問高於896MB物理地址內存時,從0xF8000000
~
0xFFFFFFFF地址空間范圍內找一段相應大小空閑的邏輯地址空間,借用一會。借用這段邏輯地址空間,建立映射到想訪問的那段物理內存(即填充內核PTE頁面表),臨時用一會,用完後歸還。這樣別人也可以借用這段地址空間訪問其他物理內存,實現了使用有限的地址空間,訪問所有所有物理內存。如下圖。
例如內核想訪問2G開始的一段大小為1MB的物理內存,即物理地址范圍為0×80000000
~
0x800FFFFF。訪問之前先找到一段1MB大小的空閑地址空間,假設找到的空閑地址空間為0xF8700000
~
0xF87FFFFF,用這1MB的邏輯地址空間映射到物理地址空間0×80000000
~
0x800FFFFF的內存。映射關系如下:
邏輯地址物理內存地址0xF87000000×800000000xF87000010×800000010xF87000020×80000002…
…0xF87FFFFF0x800FFFFF
當內核訪問完0×80000000
~
0x800FFFFF物理內存後,就將0xF8700000
~
0xF87FFFFF內核線性空間釋放。這樣其他進程或代碼也可以使用0xF8700000
~
0xF87FFFFF這段地址訪問其他物理內存。
從上面的描述,我們可以知道高端內存的最基本思想:借一段地址空間,建立臨時地址映射,用完後釋放,達到這段地址空間可以循環使用,訪問所有物理內存。
看到這里,不禁有人會問:萬一有內核進程或模塊一直佔用某段邏輯地址空間不釋放,怎麼辦?若真的出現的這種情況,則內核的高端內存地址空間越來越緊張,若都被佔用不釋放,則沒有建立映射到物理內存都無法訪問了。
3. linux kernel 內存管理-頁表、TLB
頁表用來把虛擬頁映射到物理頁,並且存放頁的保護位(即訪問許可權)。
在Linux4.11版本以前,Linux內核把頁表分為4級:
頁全局目錄表(PGD)、頁上層目錄(PUD)、頁中間目錄(PMD)、直接頁表(PT) 。
4.11版本把頁表擴展到5級,在頁全局目錄和頁上層目錄之間增加了 頁四級目錄(P4D) 。
各處處理器架構可以選擇使用5級,4級,3級或者2級頁表,同一種處理器在頁長度不同的情況可能選擇不同的頁表級數。可以使用配置宏CONFIG_PGTABLE_LEVELS配置頁表的級數,一般使用默認值。
如果選擇4級頁表,那麼使用PGD,PUD,PMD,PT;如果使用3級頁表,那麼使用PGD,PMD,PT;如果選擇2級頁表,那麼使用PGD和PT。 如果不使用頁中間目錄 ,那麼內核模擬頁中間目錄,調用函數pmd_offset 根據頁上層目錄表項和虛擬地址獲取頁中間目錄表項時 , 直接把頁上層目錄表項指針強制轉換成頁中間目錄表項 。
每個進程有獨立的頁表,進程的mm_struct實例的成員pgd指向頁全局目錄,前面四級頁表的表項存放下一級頁表的起始地址,直接頁表的頁表項存放頁幀號(PFN) 。
內核也有一個頁表, 0號內核線程的進程描述符init_task的成員active_mm指向內存描述符init_mm,內存描述符init_mm的成員pgd指向內核的頁全局目錄swapper_pg_dir 。
ARM64處理器把頁表稱為轉換表,最多4級。ARM64處理器支持三種頁長度:4KB,16KB,64KB。頁長度和虛擬地址的寬度決定了轉換表的級數,在虛擬地址的寬度為48位的條件下,頁長度和轉換表級數的關系如下所示:
ARM64處理器把表項稱為描述符,使用64位的長描述符格式。描述符的0bit指示描述符是不是有效的:0表示無效,1表示有效。第1位指定描述符類型。
在塊描述符和頁描述符中,內存屬性被拆分為一個高屬性和一個低屬性塊。
處理器的MMU負責把虛擬地址轉換成物理地址,為了改進虛擬地址到物理地址的轉換速度,避免每次轉換都需要查詢內存中的頁表,處理器廠商在管理單元里加了稱為TLB的高速緩存,TLB直譯為轉換後備緩沖區,意譯為頁表緩存。
頁表緩存用來緩存最近使用過的頁表項, 有些處理器使用兩級頁表緩存 : 第一級TLB分為指令TLB和數據TLB,好處是取指令和取數據可以並行;第二級TLB是統一TLB,即指令和數據共用的TLB 。
不同處理器架構的TLB表項的格式不同。ARM64處理器的每條TLB表項不僅包含虛擬地址和物理地址,也包含屬性:內存類型、緩存策略、訪問許可權、地址空間標識符(ASID)和虛擬機標識符(VMID)。 地址空間標識符區分不同進程的頁表項 , 虛擬機標識符區分不同虛擬機的頁表項 。
如果內核修改了可能緩存在TLB裡面的頁表項,那麼內核必須負責使舊的TLB表項失效,內核定義了每種處理器架構必須實現的函數。
當TLB沒有命中的時候,ARM64處理器的MMU自動遍歷內存中的頁表,把頁表項復制到TLB,不需要軟體把頁表項寫到TLB,所以ARM64架構沒有提供寫TLB的指令。
為了減少在進程切換時清空頁表緩存的需要,ARM64處理器的頁表緩存使用非全局位區分內核和進程的頁表項(nG位為0表示內核的頁表項), 使用地址空間標識符(ASID)區分不同進程的頁表項 。
ARM64處理器的ASID長度是由具體實現定義的,可以選擇8位或者16位。寄存器TTBR0_EL1或者TTBR1_EL1都可以用來存放當前進程的ASID,通常使用寄存器TCR_EL1的A1位決定使用哪個寄存器存放當前進程的ASID,通常使用寄存器 TTBR0_EL1 。寄存器TTBR0_EL1的位[63:48]或者[63:56]存放當前進程的ASID,位[47:1]存放當前進程的頁全局目錄的物理地址。
在SMP系統中,ARM64架構要求ASID在處理器的所有核是唯一的。假設ASID為8位,ASID只有256個值,其中0是保留值,可分配的ASID范圍1~255,進程的數量可能超過255,兩個進程的ASID可能相同,內核引入ASID版本號解決這個問題。
(1)每個進程有一個64位的軟體ASID, 低8位存放硬體ASID,高56位存放ASID版本號 。
(2) 64位全局變數asid_generation的高56位保存全局ASID版本號 。
(3) 當進程被調度時,比較進程的ASID版本號和全局版本號 。如果版本號相同,那麼直接使用上次分配的ASID,否則需要給進程重新分配硬體ASID。
存在空閑ASID,那麼選擇一個分配給進程。不存在空閑ASID時,把全局ASID版本號加1,重新從1開始分配硬體ASID,即硬體ASID從255回繞到1。因為剛分配的硬體ASID可能和某個進程的ASID相同,只是ASID版本號不同,頁表緩存可能包含了這個進程的頁表項,所以必須把所有處理器的頁表緩存清空。
引入ASID版本號的好處是:避免每次進程切換都需要清空頁表緩存,只需要在硬體ASID回環時把處理器的頁表緩存清空 。
虛擬機裡面運行的客戶操作系統的虛擬地址轉物理地址分兩個階段:
(1) 把虛擬地址轉換成中間物理地址,由客戶操作系統的內核控制 ,和非虛擬化的轉換過程相同。
(2) 把中間物理地址轉換成物理地址,由虛擬機監控器控制 ,虛擬機監控器為每個虛擬機維護一個轉換表,分配一個虛擬機標識符,寄存器 VTTBR_EL2 存放當前虛擬機的階段2轉換表的物理地址。
每個虛擬機有獨立的ASID空間 ,頁表緩存使用 虛擬機標識符 區分不同虛擬機的轉換表項,避免每次虛擬機切換都要清空頁表緩存,在虛擬機標識符回繞時把處理器的頁表緩存清空。
4. linux中物理內存和虛擬內存
vmstat是Virtual Meomory Statistics(虛擬內存統計)的縮寫,可對操作系統的虛擬內存、進程、CPU活動進行監控。他是對系統的整體情況進行統計,不足之處是無法對某個進程進行深入分析。vmstat 工具提供了一種低開銷的系統性能觀察方式。因為 vmstat 本身就是低開銷工具,在非常高負荷的伺服器上,你需要查看並監控系統的健康情況,在控制窗口還是能夠使用vmstat 輸出結果。在學習vmstat命令前,我們先了解一下Linux系統中關於物理內存和虛擬內存相關信息。
物理內存和虛擬內存區別:
我們知道,直接從物理內存讀寫數據要比從硬碟讀寫數據要快的多,因此,我們希望所有數據的讀取和寫入都在內存完成,而內存是有限的,這樣就引出了物理內存與虛擬內存的概念。
物理內存就是系統硬體提供的內存大小,是真正的內存,相對於物理內存,在linux下還有一個虛擬內存的概念,虛擬內存就是為了滿足物理內存的不足而提出的策略,它是利用磁碟空間虛擬出的一塊邏輯內存,用作虛擬內存的磁碟空間被稱為交換空間(Swap Space)。
作為物理內存的擴展,linux會在物理內存不足時,使用交換分區的虛擬內存,更詳細的說,就是內核會將暫時不用的內存塊信息寫到交換空間,這樣以來,物理內存得到了釋放,這塊內存就可以用於其它目的,當需要用到原始的內容時,這些信息會被重新從交換空間讀入物理內存。
linux的內存管理採取的是分頁存取機制,為了保證物理內存能得到充分的利用,內核會在適當的時候將物理內存中不經常使用的數據塊自動交換到虛擬內存中,而將經常使用的信息保留到物理內存。
要深入了解linux內存運行機制,需要知道下面提到的幾個方面:
首先,Linux系統會不時的進行頁面交換操作,以保持盡可能多的空閑物理內存,即使並沒有什麼事情需要內存,Linux也會交換出暫時不用的內存頁面。這可以避免等待交換所需的時間。
其次,linux進行頁面交換是有條件的,不是所有頁面在不用時都交換到虛擬內存,linux內核根據」最近最經常使用「演算法,僅僅將一些不經常使用的頁面文件交換到虛擬內存,有時我們會看到這么一個現象:linux物理內存還有很多,但是交換空間也使用了很多。其實,這並不奇怪,例如,一個佔用很大內存的進程運行時,需要耗費很多內存資源,此時就會有一些不常用頁面文件被交換到虛擬內存中,但後來這個佔用很多內存資源的進程結束並釋放了很多內存時,剛才被交換出去的頁面文件並不會自動的交換進物理內存,除非有這個必要,那麼此刻系統物理內存就會空閑很多,同時交換空間也在被使用,就出現了剛才所說的現象了。關於這點,不用擔心什麼,只要知道是怎麼一回事就可以了。
最後,交換空間的頁面在使用時會首先被交換到物理內存,如果此時沒有足夠的物理內存來容納這些頁面,它們又會被馬上交換出去,如此以來,虛擬內存中可能沒有足夠空間來存儲這些交換頁面,最終會導致linux出現假死機、服務異常等問題,linux雖然可以在一段時間內自行恢復,但是恢復後的系統已經基本不可用了。
因此,合理規劃和設計linux內存的使用,是非常重要的。
虛擬內存原理:
在系統中運行的每個進程都需要使用到內存,但不是每個進程都需要每時每刻使用系統分配的內存空間。當系統運行所需內存超過實際的物理內存,內核會釋放某些進程所佔用但未使用的部分或所有物理內存,將這部分資料存儲在磁碟上直到進程下一次調用,並將釋放出的內存提供給有需要的進程使用。
在Linux內存管理中,主要是通過「調頁Paging」和「交換Swapping」來完成上述的內存調度。調頁演算法是將內存中最近不常使用的頁面換到磁碟上,把活動頁面保留在內存中供進程使用。交換技術是將整個進程,而不是部分頁面,全部交換到磁碟上。
分頁(Page)寫入磁碟的過程被稱作Page-Out,分頁(Page)從磁碟重新回到內存的過程被稱作Page-In。當內核需要一個分頁時,但發現此分頁不在物理內存中(因為已經被Page-Out了),此時就發生了分頁錯誤(Page Fault)。
當系統內核發現可運行內存變少時,就會通過Page-Out來釋放一部分物理內存。經管Page-Out不是經常發生,但是如果Page-out頻繁不斷的發生,直到當內核管理分頁的時間超過運行程式的時間時,系統效能會急劇下降。這時的系統已經運行非常慢或進入暫停狀態,這種狀態亦被稱作thrashing(顛簸)。
總結:物理內存就是硬體提供的真實的內存,比如我們電腦內存不夠了,就會加一個內存條
虛擬內存就是從磁碟上虛擬出來的一塊邏輯內存,用做虛擬內存的磁碟空間被稱為交換空間(Swap Space
經常使用的文件會優先放在物理內存,不經常使用的文件會放到虛擬內存裡面。
5. LINUX系統的內存管理知識詳解
內存是Linux內核所管理的最重要的資源之一。內存管理系統是操作系統中最為重要的部分,因為系統的物理內存總是少於系統所需要的內存數量。虛擬內存就是為了克服這個矛盾而採用的策略。系統的虛擬內存通過在各個進程之間共享內存而使系統看起來有多於實際內存的內存容量。Linux支持虛擬內存, 就是使用磁碟作為RAM的擴展,使可用內存相應地有效擴大。核心把當前不用的內存塊存到硬碟,騰出內存給其他目的。當原來的內容又要使用時,再讀回內存。以下就是我為大家整理到的詳細LINUX系統內存管理的知識,歡迎大家閱讀!!!
LINUX系統教程:內存管理的知識詳解
一、內存使用情況監測
(1)實時監控內存使用情況
在命令行使用「Free」命令可以監控內存使用情況
代碼如下:
#free
total used free shared buffers cached
Mem: 256024 192284 63740 0 10676 101004
-/+ buffers/cache: 80604 175420
Swap: 522072 0 522072
上面給出了一個256兆的RAM和512兆交換空間的系統情況。第三行輸出(Mem:)顯示物理內存。total列不顯示核心使用的物理內存(通常大約1MB)。used列顯示被使用的內存總額(第二行不計緩沖)。 free列顯示全部沒使用的內存。Shared列顯示多個進程共享的內存總額。Buffers列顯示磁碟緩存的當前大小。第五行(Swap:)對對換空間,顯示的信息類似上面。如果這行為全0,那麼沒使用對換空間。在預設的狀態下,free命令以千位元組(也就是1024位元組為單位)來顯示內存使用情況。可以使用—h參數以位元組為單位顯示內存使用情況,或者可以使用—m參數以兆位元組為單位顯示內存使用情況。還可以通過—s參數使用命令來不間斷地監視內存使用情況:
#free –b –s2
這個命令將會在終端窗口中連續不斷地報告內存的使用情況,每2秒鍾更新一次。
(2)組合watch與 free命令用來實時監控內存使用情況:
代碼如下:
#watch -n 2 -d free
Every 2.0s: free Fri Jul 6 06:06:12 2007
total used free shared buffers cached
Mem: 233356 218616 14740 0 5560 64784
-/+ buffers/cache: 148272 85084
Swap: 622584 6656 615928
watch命令會每兩秒執行 free一次,執行前會清除屏幕,在同樣位置顯示數據。因為 watch命令不會卷動屏幕,所以適合出長時間的監測內存使用率。可以使用 -n選項,控制執行的頻率;也可以利用 -d選項,讓命令將每次不同的地方顯示出來。Watch命令會一直執行,直到您按下 [Ctrl]-[C] 為止。
二、虛擬內存的概念
(1)Linux虛擬內存實現機制
Linux虛擬內存的實現需要六種機制的支持:地址映射機制、內存分配回收機制、緩存和刷新機制、請求頁機制、交換機制、內存共享機制。
首先內存管理程序通過映射機制把用戶程序的邏輯地址映射到物理地址,在用戶程序運行時如果發現程序中要用的虛地址沒有對應的物理內存時,就發出了請求頁要求;如果有空閑的內存可供分配,就請求分配內存(於是用到了內存的分配和回收),並把正在使用的物理頁記錄在緩存中(使用了緩存機制)。 如果沒有足夠的內存可供分配,那麼就調用交換機制,騰出一部分內存。另外在地址映射中要通過TLB(翻譯後援存儲器)來尋找物理頁;交換機制中也要用到交換緩存,並且把物理頁內容交換到交換文件中後也要修改頁表來映射文件地址。
(2)虛擬內存容量設定
也許有人告訴你,應該分配2倍於物理內存的虛擬內存,但這是個不固定的規律。如果你的物理保存比較小,可以這樣設定。如果你有1G物理內存或更多的話,可以縮小一下虛擬內存。Linux會把大量的內存用做Cache的,但在資源緊張時回收回.。你只要看到swap為0或者很小就可以放心了,因為內存放著不用才是最大的浪費。
三、使甩vmstat命令監視虛擬內存使用情況
vmstat是Virtual Meomory Statistics(虛擬內存統計)的縮寫,可對操作系統的虛擬內存、進程、CPU活動進行監視。它是對系統的整體情況進行統計,不足之處是無法對某個進程進行深入分析。通常使用vmstat 5 5(表示在5秒時間內進行5次采樣)命令測試。將得到一個數據匯總它可以反映真正的系統情況。
代碼如下:
#vmstat 5 5
procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
1 0 62792 3460 9116 88092 6 30 189 89 1061 569 17 28 54 2
0 0 62792 3400 9124 88092 0 0 0 14 884 434 4 14 81 0
0 0 62792 3400 9132 88092 0 0 0 14 877 424 4 15 81 0
1 0 62792 3400 9140 88092 0 0 0 14 868 418 6 20 74 0
1 0 62792 3400 9148 88092 0 0 0 15 847 400 9 25 67 0
vmstat命令輸出分成六個部分:
(1)進程procs:
r:在運行隊列中等待的進程數 。
b:在等待io的進程數 。
(2)內存memoy:
swpd:現時可用的交換內存(單位KB)。
free:空閑的內存(單位KB)。
buff: 緩沖去中的內存數(單位:KB)。
cache:被用來做為高速緩存的內存數(單位:KB)。
(3) swap交換頁面
si: 從磁碟交換到內存的交換頁數量,單位:KB/秒。
so: 從內存交換到磁碟的交換頁數量,單位:KB/秒。
(4) io塊設備:
bi: 發送到塊設備的塊數,單位:塊/秒。
bo: 從塊設備接收到的塊數,單位:塊/秒。
(5)system系統:
in: 每秒的中斷數,包括時鍾中斷。
cs: 每秒的環境(上下文)切換次數。
(6)cpu中央處理器:
cs:用戶進程使用的時間 。以百分比表示。
sy:系統進程使用的時間。 以百分比表示。
id:中央處理器的空閑時間 。以百分比表示。
如果 r經常大於 4 ,且id經常小於40,表示中央處理器的負荷很重。 如果bi,bo 長期不等於0,表示物理內存容量太小。
四、Linux 伺服器的內存泄露和回收內存的方法
1、內存泄漏的定義:
一般我們常說的內存泄漏是指堆內存的泄漏。堆內存是指程序從堆中分配的,大小任意的(內存塊的大小可以在程序運行期決定),使用完後必須顯示釋放的內存。應用程序一般使用malloc,realloc,new等函數從堆中分配到一塊內存,使用完後,程序必須負責相應的調用free或釋放該內存塊,否則,這塊內存就不能被再次使用,我們就說這塊內存泄漏了。
2、內存泄露的危害
從用戶使用程序的角度來看,內存泄漏本身不會產生什麼危害,作為一般的用戶,根本感覺不到內存泄漏的存在。真正有危害的`是內存泄漏的堆積,這會最終消耗盡系統所有的內存。從這個角度來說,一次性內存泄漏並沒有什麼危害,因為它不會堆積,而隱式內存泄漏危害性則非常大,因為較之於常發性和偶發性內存泄漏它更難被檢測到。存在內存泄漏問題的程序除了會佔用更多的內存外,還會使程序的性能急劇下降。對於伺服器而言,如果出現這種情況,即使系統不崩潰,也會嚴重影響使用。
3、內存泄露的檢測和回收
對於內存溢出之類的麻煩可能大家在編寫指針比較多的復雜的程序的時候就會遇到。在 Linux 或者 unix 下,C、C++語言是最使用工具。但是我們的 C++ 程序缺乏相應的手段來檢測內存信息,而只能使用 top 指令觀察進程的動態內存總額。而且程序退出時,我們無法獲知任何內存泄漏信息。
使用kill命令
使用Linux命令回收內存,我們可以使用Ps、Kill兩個命令檢測內存使用情況和進行回收。在使用超級用戶許可權時使用命令「Ps」,它會列出所有正在運行的程序名稱,和對應的進程號(PID)。Kill命令的工作原理是:向Linux操作系統的內核送出一個系統操作信號和程序的進程號(PID)。
應用例子:
為了高效率回收內存可以使用命令ps 參數v:
代碼如下:
[root@www ~]# ps v
PID TTY STAT TIME MAJFL TRS DRS RSS %MEM COMMAND
2542 tty1 Ss+ 0:00 0 8 1627 428 0.1 /sbin/mingetty tty1
2543 tty2 Ss+ 0:00 0 8 1631 428 0.1 /sbin/mingetty tty2
2547 tty3 Ss+ 0:00 0 8 1631 432 0.1 /sbin/mingetty tty3
2548 tty4 Ss+ 0:00 0 8 1627 428 0.1 /sbin/mingetty tty4
2574 tty5 Ss+ 0:00 0 8 1631 432 0.1 /sbin/mingetty tty5
2587 tty6 Ss+ 0:00 0 8 1627 424 0.1 /sbin/mingetty tty6
2657 tty7 Ss+ 1:18 12 1710 29981 7040 3.0 /usr/bin/Xorg :0 -br -a
2670 pts/2 Ss 0:01 2 682 6213 1496 0.6 -bash
3008 pts/4 Ss 0:00 2 682 6221 1472 0.6 /bin/bash
3029 pts/4 S+ 0:00 2 32 1783 548 0.2 ping 192.168.1.12
3030 pts/2 R+ 0:00 2 73 5134 768 0.3 ps v
然後如果想回收Ping命令的內存的話,使用命令:
代碼如下:
# Kill -9 3029
使用工具軟體
Memprof是一個非常具有吸引力且非常易於使用的軟體,它由Red Hat的Owen Talyor創立。這個工具是用於GNOME前端的Boehm-Demers-Weiser垃圾回收器。這個工具直接就可以執行,並且其工作起來無需對源代碼進行任何修改。在程序執行時,這個工具會以圖形化的方式顯示內存的使用情況。
相關介紹:Linux
嚴格來講,Linux這個詞本身只表示Linux內核,但人們已經習慣了用Linux來形容整個基於Linux內核,並且使用GNU 工程各種工具和資料庫的操作系統。
Linux擁有以下特性:類似於Unix的基本思想,支持完全免費與自由傳播,完全兼容POSIX1.0標准,支持多用戶、多任務、有著良好的界面、支持多種平台。Linux 能運行主要的UNIX工具軟體、應用程序和網路協議。它支持32位和64位硬體。Linux繼承了Unix以網路為核心的設計思想,是一個性能穩定的多用戶網路操作系統。
Linux有著許多不同的版本,但它們都使用了Linux內核。Linux可安裝在各種計算機硬體設備中,比如手機、平板電腦、路由器、視頻游戲控制台、台式計算機、大型機和超級計算機。
6. Linux 內核的內存管理 - 概念
Concepts overview — The Linux Kernel documentation
Linux中的內存管理是一個復雜的系統,經過多年的發展,它包含越來越多的功能,以支持從 MMU-less microcontrollers 到 supercomputers 的各種系統。
沒有MMU內存管理的系統被稱為 nommu ,它值得寫一份專門的文檔進行描述。
盡管有些概念是相同的,這里我們假設MMU可用,CPU可以將虛擬地址轉換為物理地址。
計算機系統中的物理內存是有限資源,即便支持內存熱插拔,其可以安裝的內存也有限的。物理內存不一定必須是連續的;它可以作為一組不同的地址范圍被訪問。此外,不同的CPU架構,甚至同架構的不同實現對如何定義這些地址范圍都是不同的。
這使得直接處理物理內存異常復雜,為了避免這種復雜性,開發了 虛擬內存 (virtual memory) 的概念。
虛擬內存從應用軟體中抽象出物理內存的細節,只允許在物理內存中保留需要的信息 (demand paging) ,並提供一種機制來保護和控制進程之間的數據共享。
通過虛擬內存,每次內存訪問都訪問一個 虛擬地址 。當CPU對從系統內存讀取(或寫入)的指令進行解碼時,它將該指令中編碼的虛擬地址轉換為內存控制器可以理解的物理地址。
物理內存被切分為 頁幀 page frames 或 頁 pages 。頁的大小是基於架構的。一些架構允許從幾個支持的值中選擇頁大小;此選擇在內核編譯時設置到內核配置。
每個物理內存頁都可以映射為一個或多個 虛擬頁(virtual pages) 。映射關系描述在 頁表(page tables) 中,頁表將程序使用的虛擬地址轉換為物理內存地址。頁表以層次結構組織。
最底層的表包含軟體使用的實際內存頁的物理地址。較高層的表包含較低層表頁的物理地址。頂層表的指針駐留在寄存器中。
當CPU進行地址轉換的時候,它使用寄存器訪問頂級頁表。
虛擬地址的高位,用於頂級頁表的條目索引。然後,通過該條目訪問下級,下級的虛擬地址位又作為其下下級頁表的索引。虛擬地址的最低位定義實際頁內的偏移量。
地址轉換需要多次內存訪問,而內存訪問相對於CPU速度來說比較慢。為了避免在地址轉換上花費寶貴的處理器周期,CPU維護著一個稱為 TLB (Translation Lookaside Buffer)的用於地址轉換緩存(cache)。通常TLB是非常稀缺的資源,需要大內存工作應用程序會因為TLB未命中而影響性能。
很多現代CPU架構允許頁表的高層直接映射到內存頁。例如,x86架構,可以通過二級、三級頁表的條目映射2M甚至1G內存頁。在Linux中,這些內存頁稱為 大頁 (Huge) 。大頁的使用顯著降低了TLB的壓力,提高了TLB命中率,從而提高了系統的整體性能。
Linux提供兩種機制開啟使用大頁映射物理內存。
第一個是 HugeTLB 文件系統,即 hugetlbfs 。它是一個偽文件系統,使用RAM作為其存儲。在此文件系統中創建的文件,數據駐留在內存中,並使用大頁進行映射。
關於 HugeTLB Pages
另一個被稱為 THP (Transparent HugePages) ,後出的開啟大頁映射物理內存的機制。
與 hugetlbfs 不同,hugetlbfs要求用戶和/或系統管理員配置系統內存的哪些部分應該並可以被大頁映射;THP透明地管理這些映射並獲取名稱。
關於 Transparent Hugepage Support
通常,硬體對不同物理內存范圍的訪問方式有所限制。某些情況下,設備不能對所有可定址內存執行DMA。在其他情況下,物理內存的大小超過虛擬內存的最大可定址大小,需要採取特殊措施來訪問部分內存。還有些情況,物理內存的尺寸超過了虛擬內存的最大可定址尺寸,需要採取特殊措施來訪問部分內存。
Linux根據內存頁的使用情況,將其組合為多個 zones 。比如, ZONE_DMA 包含設備用於DMA的內存, ZONE_HIGHMEM 包含未永久映射到內核地址空間的內存, ZONE_NORMAL 包含正常定址內存頁。
內存zones的實際層次架構取決於硬體,因為並非所有架構都定義了所有的zones,不同平台對DMA的要求也不同。
多處理器機器很多基於 NUMA (Non-Uniform Memory Access system - 非統一內存訪問系統 )架構。 在這樣的系統中,根據與處理器的「距離」,內存被安排成具有不同訪問延遲的 banks 。每個 bank 被稱為一個 node ,Linux為每個 node 構造一個獨立的內存管理子系統。 Node 有自己的zones集合、free&used頁面列表,以及各種統計計數器。
What is NUMA?
NUMA Memory Policy
物理內存易失,將數據放入內存的常見情況是讀取文件。讀取文件時,數據會放入 頁面緩存(page cache) ,可以在再次讀取時避免耗時的磁碟訪問。同樣,寫文件時,數據也會被放入 頁面緩存 ,並最終進入存儲設備。被寫入的頁被標記為 臟頁(dirty page) ,當Linux決定將其重用時,它會將更新的數據同步到設備上的文件。
匿名內存 anonymous memory 或 匿名映射 anonymous mappings 表示沒有後置文件系統的內存。這些映射是為程序的stack和heap隱式創建的,或調用mmap(2)顯式創建的。通常,匿名映射只定義允許程序訪問的虛擬內存區域。讀,會創建一個頁表條目,該條目引用一個填充有零的特殊物理頁。寫,則分配一個常規物理頁來保存寫入數據。該頁將被標記為臟頁,如果內核決定重用該頁,則臟頁將被交換出去 swapped out 。
縱貫整個系統生命周期,物理頁可用於存儲不同類型的數據。它可以是內核內部數據結構、設備驅動DMA緩沖區、讀取自文件系統的數據、用戶空間進程分配的內存等。
根據內存頁使用情況,Linux內存管理會區別處理。可以隨時釋放的頁面稱為 可回收(reclaimable) 頁面,因為它們把數據緩存到了其他地方(比如,硬碟),或者被swap out到硬碟上。
可回收頁最值得注意的是 頁面緩存 和 匿名頁面 。
在大多數情況下,存放內部內核數據的頁,和用作DMA緩沖區的頁無法重用,它們將保持現狀直到用戶釋放。這樣的被稱為 不可回收頁(unreclaimable) 。
然而,在特定情況下,即便是內核數據結構佔用的頁面也會被回收。
例如,文件系統元數據的緩存(in-memory)可以從存儲設備中重新讀取,因此,當系統存在內存壓力時,可以從主內存中丟棄它們。
釋放可回收物理內存頁並重新調整其用途的過程稱為 (surprise!) reclaim 。
Linux支持非同步或同步回收頁,取決於系統的狀態。
當系統負載不高時,大部分內存是空閑的,可以立即從空閑頁得到分配。
當系統負載提升後,空閑頁減少,當達到某個閾值( low watermark )時,內存分配請求將喚醒 kswapd 守護進程。它將以非同步的方式掃描內存頁。如果內存頁中的數據在其他地方也有,則釋放這些內存頁;或者退出內存到後置存儲設備(關聯 臟頁 )。
隨著內存使用量進一步增加,並達到另一個閾值- min watermark -將觸發回收。這種情況下,分配將暫停,直到回收到足夠的內存頁。
當系統運行時,任務分配並釋放內存,內存變得碎片化。
雖然使用虛擬內存可以將分散的物理頁表示為虛擬連續范圍,但有時需要分配大的連續的物理內存。這種需求可能會提升。例如,當設備驅動需要一個大的DMA緩沖區時,或當THP分配一個大頁時。
內存地址壓縮(compaction ) 解決了碎片問題。
該機制將佔用的頁從內存zone的下部移動到上部的空閑頁。壓縮掃描完成後,zone開始處的空閑頁就並在一起了,分配較大的連續物理內存就可行了。
與 reclaim 類似, compaction 可以在 kcompactd守護進程中非同步進行,也可以作為內存分配請求的結果同步進行。
在存在負載的機器上,內存可能會耗盡,內核無法回收到足夠的內存以繼續運行。
為了保障系統的其餘部分,引入了 OOM killer 。
OOM killer 選擇犧牲一個任務來保障系統的總體健康。選定的任務被killed,以期望在它退出後釋放足夠的內存以繼續正常的操作。
7. LINUX的五大內核是什麼
你問的應該是模塊吧 去QQ群:91624328吧!linux內核五大模塊 Linux內核的五大模塊 1.進程調度模塊 2.內存管理模塊 3.文件系統模塊 4.進程間通信模塊 5.網路介面模塊 進程調度模塊
用來負責控制進程對CPU 資源的使用。所採取的調度策略是各進程能夠公平合理地訪問CPU, 同時保證內核能及時地執行硬體操作。 內存管理模塊
用於確保所有進程能夠安全地共享機器主內存區, 同時, 內存管理模塊還支持虛擬內存管理方式, 使得Linux 支持進程使用比實際內存空間更多的內存容量。並可以利用文件系統, 對暫時不用的內存數據塊交換到外部存儲設備上去, 當需要時再交換回來。 文件系統模塊
用於支持對外部設備的驅動和存儲。虛擬文件系統模塊通過向所有的外部存儲設備提供一個通用的文件介面,隱藏了各種硬體設備的不同細節。從而提供並支持與其它操作系統兼容的多種文件系統格式。 進程間通信模塊
用於支持多種進程間的信息交換方式 網路介面模塊
提供對多種網路通信標準的訪問並支持許多網路硬體。
8. Linux進程內存如何管理
內存管理的主要工作就是對物理內存進行組織,然後對物理內存的分配和回收。但是Linux引入了虛擬地址的概念。
虛擬地址的作用
如果用戶進程直接操作物理地址會有以下的壞處:
1、 用戶進程可以直接操作內核對應的內存,破壞內核運行。
2、 用戶進程也會破壞其他進程的運行
CPU中寄存器中存儲的是邏輯地址,需要進行映射才能轉化為對應的物理地址,然後獲取對應的內存。
通過引入邏輯地址,每個進程都擁有單獨的邏輯地址范圍。
當進程申請內存的時候,會為其分配邏輯地址和物理地址,並將邏輯地址和物理地址做一個映射。
9. linux內核主要由哪幾個部分組成
一個完整的Linux內核一般由5部分組成,它們分別是內存管理、進程管理、進程間通信、虛擬文件系統和網路介面。
1、內存管理
內存管理主要完成的是如何合理有效地管理整個系統的物理內存,同時快速響應內核各個子系統對內存分配的請求。
Linux內存管理支持虛擬內存,而多餘出的這部分內存就是通過磁碟申請得到的,平時系統只把當前運行的程序塊保留在內存中,其他程序塊則保留在磁碟中。在內存緊缺時,內存管理負責在磁碟和內存間交換程序塊。
2、進程管理
進程管理主要控制系統進程對CPU的訪問。當需要某個進程運行時,由進程調度器根據基於優先順序的調度演算法啟動新的進程。:Linux支持多任務運行,那麼如何在一個單CPU上支持多任務呢?這個工作就是由進程調度管理來實現的。
在系統運行時,每個進程都會分得一定的時間片,然後進程調度器根據時間片的不同,選擇每個進程依次運行,例如當某個進程的時間片用完後,調度器會選擇一個新的進程繼續運行。
由於切換的時間和頻率都非常的快,由此用戶感覺是多個程序在同時運行,而實際上,CPU在同一時間內只有一個進程在運行,這一切都是進程調度管理的結果。
3、進程間通信
進程間通信主要用於控制不同進程之間在用戶空間的同步、數據共享和交換。由於不用的用戶進程擁有不同的進程空間,因此進程間的通信要藉助於內核的中轉來實現。
一般情況下,當一個進程等待硬體操作完成時,會被掛起。當硬體操作完成,進程被恢復執行,而協調這個過程的就是進程間的通信機制。
4、虛擬文件系統
Linux內核譽衫鉛中的虛擬文件系統用一個通用的文件模型表示了各種不同的文件系統,這個文件模型屏蔽了很多具體文件系統的差異,使Linux內核支持很多不同的文件系統。
這個文件系統可以分為邏輯文件系統和設備驅動程序:邏輯文件系統指Linux所支持的文件系統,例如ext2、ext3和fat等;設備驅動程序指為每一種硬體控制器所編寫的設備驅動程序模塊。
5、網路介面
網路介面提供了對各種網路標準的實現和各種網路硬體的支持。網路介面一般分為網路協議慶好和網路驅動程序。網路協議部分負責實現每一種可能的網路傳輸協議。
網路設備驅動程序則主要負責與硬體設備進行通信,每一種可能的網路硬體設備都有相應的設備驅動程序。
(9)linux內存管理內核擴展閱讀:
Linux 操作系統的誕生、發展和成長過程始終依賴著五個重要支柱:UNIX操作系統、MINIX操作系統、GNU計劃、POSIX標准和Internet 網路。
1981 年IBM公司推出微型計算機IBM PC。
1991年,GNU計劃已經開發出了許多工具軟體,最受期盼的GNU C編譯器已經出現,GNU的操作系統核心HURD一直處於實驗階段,沒有任何可用性,實質上也沒能開發出完整的GNU操作系統,但是GNU奠定了Linux用戶基礎和開發環境。
1991年初,林納斯·托瓦茲開始在一台386sx兼容微機上學習minix操作系統。1991年4月,林納斯·托瓦茲開始醞釀並著手編制自己的操作系統。
1991 年4 月13 日在comp.os.minix 上發布說自己已經成功地將bash 移植到了minix 上,而且已經愛不釋手、不能離開這個shell軟體了。
1993年,大約有100餘名程序員參與了Linux內核代碼編寫/修改工作,其中核心組由5人組成,此時Linux 0.99的代碼大約有十萬行,用戶大約有10萬左右。
1994年3月,Linux1.0發布,代碼量17萬行,當時是按照完全自由免費的協議發布,隨後正式採用GPL協議。
1995年1月,Bob Young創辦了RedHat(小紅帽),以GNU/Linux為核心,集成了400多個源代碼開放的程序模塊,搞出了一種冠以品牌的Linux,即RedHat Linux,稱為Linux"發行版",在市場上出售。這在經營模式上是一種創舉。
2001年1月,Linux 2.4發布,它進一步地提升了SMP系統的擴展性,同時它也集成了很多用於支持桌面系統的特性:USB,PC卡(PCMCIA)的支持,內置的即插即用,等等功能。
2003年12月,Linux 2.6版內核發布,相對於2.4版內核2.6在對系統的支持都有很大的變化。
2004年的第1月,SuSE嫁到了Novell,SCO繼續頂著罵名四處強行「塌棚化緣」, Asianux, MandrakeSoft也在五年中首次宣布季度贏利。3月,SGI宣布成功實現了Linux操作系統支持256個Itanium 2處理器。