Linux內存管理

1.Linux進程內存分佈編程

  進程內存分佈如上圖:編程語言

  [1]Linux沒有采用分段機制,邏輯地址和虛擬地址是一個概念。所謂虛擬地址,就是物理地址的映射。虛擬內存開始時不對應任何內存,直接使用會引起段錯誤,不進入內核就接觸不到物理內存地址,只會接觸到虛擬內存地址。虛擬內存地址必須映射物理內存(或者硬盤上的文件)之後才能存儲數據 (數據存儲在物理內存上,打印地址爲虛擬內存地址)。而內存分配其實就是虛擬內存地址映射物理內存的過程,內存回收則是解除映射關係的過程。 虛擬內存中,0~3G是用戶空間,3~4G是內核空間。一般所講內存地址,其實都不是真正意義上的物理內存的地址,而是虛擬內存地址。函數

  [2]內核空間中存放的是內核代碼和數據,而進程的用戶空間中存放的是用戶程序的代碼和數據。spa

  [3]例如,32位系統中,建立了一個進程,則當前進程擁有32位的虛擬地址空間(32位系統只能表示到4G),由於其中有3G的用戶內存,因此若是用malloc申請內存時,最大申請的總長度能夠接近3G,由於此時並不涉及物理內存。而若是malloc後對內存進行操做,例如memset爲0,由於此時須要訪問物理內存,因此會產生一個缺頁異常,把數據寫入到物理內存。所以這時候申請的總長度就是當前可用的物理內存。blog

2.用戶空間進程

  進程的代碼和數據存放於用戶空間,對於任何一個進程,都會涉及到不一樣的內存段。內存

  此處應當這樣理解:Linux系統把內存分爲內核空間和用戶空間,用戶空間給進程使用。另外不能和某個具體語言的編譯器內存分區混淆,意思就是提到用戶空間,就是如下的分段管理,具體到某個編程語言的內存處理是在這個之上的。編譯器

  [1]用戶空間的內存被分爲幾個段(圖中自下向上說明):編譯

    代碼段:  代碼段是用來存放可執行文件的操做指令,也就是說是它是可執行程序在內存中的鏡像。很明顯這部份內存是隻讀的。變量

    數據段:  數據段用來存放可執行文件中已初始化(非0)的全局變量。若是初始化爲0,則會被放到BSS段。

    BSS段:  BSS段包含了程序中未初始化全局變量,在內存中bss段所有置零。這意思就是建立一個爲初始化的全局變量會被置0。

    堆:    堆用於存放進程運行中被動態分配的內存段。使用malloc分配的內存就是從堆上面分配。

    mmap段: 這個用於mmap系統調用的內存分配。

    棧:    棧存放程序臨時建立的局部變量。

    BSS段和數據段區別:全局變量若是初始化爲非0,則放到數據段,若是未初始化或者初始化爲0,則放到BSS段。

    另外注意的是statis類型的變量,即便在函數內聲明,也屬於全局變量。

  [2]進程的內存空間就是在上面那些段中使用內存。可使用cat /proc/<pid>/maps命令,查看進程使用的內存區域地址:

      

3.內核空間

 

4.內存映射mmap

   [1]原理:調用mmap後,在虛擬空間中分配一段連續的內存,此時只是邏輯映射,並無分配物理內存。當訪問這段空間時,產生缺頁中斷,這時候是首先在swap頁面中查找,若是沒找到,則將硬盤的文件讀到物理內存中。

   [2]mmap主要有兩種用法,第一個是父子進程之間共享內存的做用。另外一個是把磁盤文件映射到進程的虛擬地址空間。

5.top命令

   VIRT:一個進程所使用的虛擬內存的總數。它包括共享庫、共享內存、棧、堆,全部已申請的總內存空間。VIRT也就是虛擬內存。

   RES:進程正在使用的實際物理內存,不包括SWAP。

   SHR:共享內存大小。這個是物理內存。

   DATA:棧內存+堆內存。

相關文章
相關標籤/搜索