一.Linux內存
1. Linux內存管理的硬件結構
圖1
-
- CPU最開始訪問虛擬地址:
訪問數據前首先要獲得數據的訪問地址。物理地址
1.2.MMU (完成地址的轉換)
1.2.1. TLB:存儲頁錶轉換的表項(TLB命中)
緩存了上一次虛擬地址訪問物理地址的記錄,便於加快訪問速度。如果沒有命中上次的記錄則只能直接訪問存儲器的頁表了(成爲TLB Miss),
1.2.2. MMU訪問一級緩存
當虛擬地址跟物理地址轉換完成後則可以到緩存中查找是否存在訪問的數據
物理索引和物理標籤的方式(PIPT),上圖訪問緩存的方式是通過地址編碼的方式來訪問。
1.2.2.1. 訪問地址的方式會分成三個部分:
- 偏移域
- 索引域
- 標記域
1.2.3.MMU訪問二級緩存
A.如果一級緩存沒有找到則繼續查找二級緩存,當二級緩存也沒有數據時最後訪問主存儲器。
B.當系統內存短缺時,Linux有個頁面回收的機制,把常用的匿名頁面放到Swap分區中,以便騰出物理內存。
2. 內存地址分類
內存的分頁:按需分配
2.1. 物理地址
2.2. 虛擬地址
包含:線性地址,邏輯地址
2.2.1. 邏輯地址
和段相關的,是段的偏移地址
2.2.2. 線性地址
3. 虛擬地址和物理地址的轉換
3.1.
即圖1中MMU單元是如何訪問頁表的
圖2(虛擬地址和物理地址轉換)
3.2.缺頁中斷
即虛擬地址到物理地址的映射關係
3.2.1.匿名頁面:
3.2.2. page cache :關聯具體緩存的頁面
3.2.3. 頁面分配器/夥伴算法
3.2.3.slab機制
當內存短缺時會使用slab機制分配頁面
3.2.4. 頁面回收
A.當內存短缺時,通常是匿名頁面和page cache ,系統有一個內核守護線程,當內存減少到一個閾值時就會被喚醒。
通常使用最近最少使用算法回收
LRU(List resontory used ,最近最少使用 )匿名頁面和page cache 通常存放在該鏈表中。列表又分爲:
B.匿名頁面是不能被drop掉,是私有數據,要寫到交換分區中:Swap ,當進程需要這些數據時,缺頁中斷會重新把Swap 中的數據讀取到匿名頁面中
3.2.5. 反向映射
老的內核版本:頁面回收,頁面所有的用戶定義vma 的鏈接斷開,
3.2.6. Huge Page (大頁 2M—1G)
減少頁面訪問次數
3.2.7. 頁遷移
3.2.8.內存規整
調整內存空間,管理碎片內存。
實現原理:room的掃描器,從頭部向尾部掃描,有哪些頁面可以遷移。可以遷移到空閒頁面,以便騰出大的物理空間。
3.2.9. OOM
當以上所有內存回收策略全部失敗後只能進行內存的回收。
二.Linux內存管理工具
1. JVM與Linux glibc
1.1. 虛擬內存佔用
Linux glibc >= 2.10 (RHEL 6) malloc may show excessive virtual memory usage)
通過export MALLOC_ARENA_MAX=4可以解決VSZ佔用過高的問題
1.2.pmap 查看進程的內存分配
pmap –d –x PID
1.3. gdb分析內存塊:
gdb --batch --19774 75 -ex "dump memory map.dump 0x7f2bceda1000 0x7f2bcef2b000
1.4. perf開啓監控棧函數調用
官方安裝地址介紹:
https://www.fosslinux.com/7069/installing-and-using-perf-in-ubuntu-and-centos.htm
https://blog.csdn.net/zl1zl2zl3/article/details/82498125
Perf 主要是性能分析工具
1.4.1 分析命令
perf record -g -p 19774 ( 生成文件 )
perf report -I perf.data
perf mem report -i perf.data
1.4.1.1 內存分析結果
1.4.1.2 結果參數介紹
A.Samples:
B. Symbol:
C. Shared Object :
Data Symbol :
1.4.2. CPU 分析
1.4.2.1.命令
perf record -g -e cpu-clock ./perf_r
生成perf.data 由於我們程序是cpu是cpu密集型,所有我只關注了cpu始終(-e cpu-clock )
perf report -g 讀取perf.data文件
1.4.2.2.
perf record -F 99 –p PID
1.5.nmon 性能檢測工具
1.5.1. 下載
wget http://sourceforge.net/projects/nmon/files/download/nmon_x86_12a.zip/download
需要查看當前系統版本適合下載對應的nmon版本,參考官網
1.5.2.解壓
unzip download #此處要留意,下載的包是存在 “download”目錄下
1.5.3. 增加權限並修改位置
chmod +x nmon_x86_rhel52
mv nmon_x86_rhel52 /usr/bin/nmon
1.5.4. 啓動nmon
直接執行[root@XXX]# nmon
1.5.5. 問題
注意** 有時會報 nmon: error while loading shared libraries: libncurses.so.5: cannot open shared object file: No such file or directory 的錯誤,是加載共享庫時找不到文件,需要重新下載。
yum install ncurses-devel.i686 -y
下載完成就可以打開 nmon視圖了
1.5.6. 顯示命令
命令 |
說明 |
c |
提供關於物理CPU使用的詳細信息 |
m |
提供內存使用的詳細信息:系統(內核)和進程,活動虛擬內存 |
d |
提供關於磁盤,磁盤類型大小,可用空間,卷組,適配器等更詳細的信息 |
t |
當前進程詳細情 |
P |
Paging space 使用情況 |
k |
顯示內核信息 |
+ |
Nmon 結果保存爲文件 |
1.5.7. 各個命令結果集解釋說明
1.5.7.1. CPU命令結果集
1.6.火焰圖
工具地址:https://github.com/brendangregg/FlameGraph.git
2. Linux 系統內存管理
2.1. brk 函數 /sbrk 函數
Heap內存區的管理
Linux的運行時堆由malloc 創建。
在高併發請求的條件下容易產生內存碎片,
2.2.mmap/unmap
Glibc 會事先分配一段內存,eg:128K,減少對系統函數的調用
2.3. tcmalloc
3.內存池
3.1. ZMQ內存池
A.預讀,預取
B.lock-free
C. 動態調整內存塊
D.利用即將釋放的內存塊