Linux 內存相關問題匯總(一)

2019-07-08   linux內核

linux 內存是後台開發人員,需要深入了解的計算機資源。合理的使用內存,有助於提升機器的性能和穩定性。本文主要介紹 linux 內存組織結構和頁面布局,內存碎片產生原因和優化算法,linux 內核幾種內存管理的方法,內存使用場景以及內存使用的那些坑。從內存的原理和結構,到內存的算法優化,再到使用場景,去探尋內存管理的機制和奧秘。

一、走進 linux 內存

1、內存是什麼?

1)內存又稱主存,是 CPU 能直接尋址的存儲空間,由半導體器件製成

2)內存的特點是存取速率快

2、內存的作用

1)暫時存放 cpu 的運算數據

2)硬碟等外部存儲器交換的數據

3)保障 cpu 計算的穩定性和高性能

二、 linux 內存地址空間

1、linux 內存地址空間 Linux 內存管理全貌

2、內存地址——用戶態&內核態

  • 用戶態:Ring3 運行於用戶態的代碼則要受到處理器的諸多
  • 內核態:Ring0 在處理器的存儲保護中,核心態
  • 用戶態切換到內核態的 3 種方式:系統調用、異常、外設中斷
  • 區別:每個進程都有完全屬於自己的,獨立的,不被干擾的內存空間;用戶態的程序就不能隨意操作內核地址空間,具有一定的安全保護作用;內核態線程共享內核地址空間;

3、內存地址——MMU 地址轉換

  • MMU 是一種硬體電路,它包含兩個部件,一個是分段部件,一個是分頁部件
  • 分段機制把一個邏輯地址轉換為線性地址
  • 分頁機制把一個線性地址轉換為物理地址

4、內存地址——分段機制

1) 段選擇符

  • 為了方便快速檢索段選擇符,處理器提供了 6 個分段寄存器來緩存段選擇符,它們是: cs,ss,ds,es,fs 和 gs
  • 段的基地址(Base Address):在線性地址空間中段的起始地址
  • 段的界限(Limit):在虛擬地址空間中,段內可以使用的最大偏移量

2) 分段實現

  • 邏輯地址的段寄存器中的值提供段描述符,然後從段描述符中得到段基址和段界限,然後加上邏輯地址的偏移量,就得到了線性地址


5、內存地址——分頁機制(32 位)

  • 分頁機制是在分段機制之後進行的,它進一步將線性地址轉換為物理地址
  • 10 位頁目錄,10 位頁表項, 12 位頁偏移地址
  • 單頁的大小為 4KB

6、用戶態地址空間

  • TEXT:代碼段可執行代碼、字符串字面值、只讀變量
  • DATA:數據段,映射程序中已經初始化的全局變量
  • BSS 段:存放程序中未初始化的全局變量
  • HEAP:運行時的堆,在程序運行中使用 malloc 申請的內存區域
  • MMAP:共享庫及匿名文件的映射區域
  • STACK:用戶進程棧

7、內核態地址空間

  • 直接映射區:線性空間中從 3G 開始最大 896M 的區間,為直接內存映射區
  • 動態內存映射區:該區域由內核函數 vmalloc 來分配
  • 永久內存映射區:該區域可訪問高端內存
  • 固定映射區:該區域和 4G 的頂端只有 4k 的隔離帶,其每個地址項都服務於特定的用途,如: ACPI_BASE 等

8、進程內存空間

  • 用戶進程通常情況只能訪問用戶空間的虛擬地址,不能訪問內核空間虛擬地址
  • 內核空間是由內核負責映射,不會跟著進程變化;內核空間地址有自己對應的頁表,用戶進程各自有不同額頁表