linux 程序管理和記憶體分配
1、程序相關概念
程序:正在執行中的程式
核心功用:程序管理、檔案系統、網路功能、記憶體管理、驅動程式、安全功能等
Process:執行中的程式的一個副本,是被載入記憶體的一個指令集合
程序 ID(Process ID,PID)號碼被用來標記各個程序
通常從執行程序的使用者來繼承,存在生命週期
task struct 任務結構表:Linux 核心儲存程序資訊的資料結構格式
task list 任務列表:多個任務的 task struct 組成的連結串列
程序建立:
都由其父程序建立,父好關係,CoW(寫時複製,不發生改變時父子都指向同一檔案;發生改變時,則複製)
init:第一個程序(centos6:init,centos7:systemd)
守護程序:隨著計算機的開啟、關閉而隨之開啟、關閉。
2、程序,執行緒和協程:
注:一個程序裡至少有一個執行緒;執行緒之間由作業系統進行排程,包括程序中使用的資源也由作業系統進行排程;協程相當於執行緒中的語句塊,由執行緒控制。
3、Page Frame:頁框,用儲存頁面資料,儲存 Page,每個程序要使用的分配空間
虛擬記憶體(線性記憶體):程序執行的時候以為自己擁有了全部的記憶體空間
實體地址空間和線性地址空間:
MMU:負責轉換線性和實體地址(虛擬記憶體和實體記憶體)
TLB:翻譯後備緩衝器,用於儲存虛擬地址和實體地址對映關係的快取
LRU:近期最少使用演算法,釋放記憶體
4、使用者空間和核心空間:
5、程序之間基本狀態和轉換:
建立狀態:程序在建立時需要申請一個空白 PCB(程序控制塊),向其中填寫控制和管理程序的資訊,完成資源分配。如果建立工作無法完成,比如資源無法滿足,就無法被排程執行,把此時程序所處狀態稱為建立狀態。
就緒狀態:程序已準備好,已分配到所需資源,只要分配到 CPU 就能夠立即執行。
執行狀態:程序處於就緒狀態被排程後,程序進入執行狀態。
阻塞狀態:正在執行的程序由於某些事件(I/O 請求,申請快取區失敗)而暫時無法執行,程序受到阻塞,在滿足請求時進入就緒狀態等待系統呼叫。
終止狀態:程序結束,或出現錯誤,或被系統終止,進入終止狀態,無法再執行。
狀態之間轉換六種情況:
執行 → 就緒:1,主要是程序佔用 CPU 的時間過長,而系統分配給該程序佔用 CPU 的時間是有限的;2,在採用搶先式優先順序排程演算法的系統中,當有更高優先順序的程序要執行時,該程序就被迫讓出 CPU,該程序便由執行狀態轉變為就緒狀態。
就緒 → 執行:執行的程序的時間片用完,排程就轉到就緒佇列中選擇合適的程序分配 CPU。
執行 → 阻塞:正在執行的程序因發生某等待事件而無法執行,則程序由執行狀態變為阻塞狀態如發生了 I/O 請求。
阻塞 → 就緒:程序所等待的事件已經發生,就進入就緒佇列。
以下兩種狀態是不可能發生的:
阻塞 → 執行:即使給阻塞程序分配 CPU,也無法執行,作業系統在進行排程時,不會從阻塞佇列進行挑選,而是從就緒佇列中選取。
就緒 → 阻塞:就緒態根本就沒有執行,談不上進入阻塞態。
6、IPC 程序間通訊:
同一主機:
pipe 管道,一個寫入管道檔案,一個讀(單向)
socket 套接字檔案,程序間交換資料(雙工工作方式)
signal 訊號
shm shared memory,共享記憶體
semaphore 訊號量,一種計數器,分配資源
不同主機:
socket ip 和埠號
RPC 遠端過程呼叫
MQ 訊息佇列,如:Kafka , RabbitMQ,ActiveMQ
7、程序優先順序
實時程序(realtime),基於 FIFO 先進先出或 RR 輪詢
非實時程序:nice 按時間片分配程序
取 139 個佇列,將相同優先順序的放在一個佇列中,執行一個時間片後從執行佇列轉至過期佇列。輪迴執行佇列和過期佇列互調,再執行。
程序優先順序:
系統優先順序:數字越小,優先順序越高
0-139:各有 140 個執行佇列和過期佇列
實時優先順序:99-0 值最大優先順序最高
nice 值:-20 到 19,對應系統優先順序 100-139
Big 0:時間複雜度,用時和規模的關係
0(1),O(logn),O(n)線性,O(n^2)拋物線,O(2^n)
8、程序狀態:
Linux 核心:搶佔式多工,按時間片分配任務
程序型別:
守護程序:daemon,在系統引|導過程中啟動的程序,和終端無關程序
前臺程序:跟終端相關,通過終端啟動的程序,使用者執行命令等
注意:兩者可相互轉化
程序狀態:
執行態:running
就緒態:ready
睡眠態:
可中斷:interruptable
不可中斷:uninterruptable
停止態:stopped,暫停於記憶體,但不會被排程,除非手動啟動
僵死態:zombie,結束程序,父程序結束前,子程序不關閉
9、程序工具
9.1 系統管理工具:
程序的分類:
CPU-Bound:CPU 密集型,非互動
編譯安裝、大量計算等
IO-Bound:IO 密集型,互動
拷貝大檔案等 DMA:直接記憶體訪問
Linux 系統狀態的檢視及管理工具:
pstree,ps,pidof,pgrep,top,htop,glance,pmap,vmstat,dstat,kill,pkill,job,bg,fg,nohup
Linux 系統各程序的相關資訊均儲存在 /proc/PID 目錄下的各檔案中
9.2 程序管理工具 PS 詳解:
ps [OPTION]... 支援三種選項: UNIX 選項 如-A -e BSD 選項 如 a GNU 選項 如--help
選項:預設顯示當前終端中的程序 a 選項包括所有終端中的程序 x 選項包括不連結終端的程序 u 選項顯示程序所有者的資訊(有效使用者) f 選項顯示程序樹,相當於--forest k|--sort 屬性對屬性排序,屬性前加-表示倒序 o 屬性...選項顯示定製的資訊 pid、cmd、%cpu、%mem L 顯示支援的屬性列
ps axo pid,%cpu,%mem,tty k %cpu -C cmdlist 指定命令,多個命令用,分隔,ps -C dd -L 顯示執行緒 -e 顯示所有程序,相當於-A -f 顯示完整格式程式資訊 -F 顯示更完整格式的程序資訊 -H 以程序層級格式顯示程序相關資訊 -u userlist 指定有效的使用者 ID 或名稱 -U userlist 指定真正的使用者 ID 或名稱 -g gid 或 groupname 指定有效的 gid 或組名稱 -G gid 或 groupname 指定真正的 gid 或組名稱 -p pid 顯示指 pid 的程序 --ppid pid 顯示屬於 pid 的子程序 -M 顯示 SELinux 資訊,相當於 Z
PS 輸出屬性: VSZ:Virtual memory SiZe,虛擬記憶體集,線性記憶體 RSS:ReSident Size,常駐記憶體集 STAT:程序狀態 R:running S:interruptable sleeping,可中斷的休眠 D:uninterruptable sleeping,不可中斷的休眠 T:stopped,停止態 Z:zombie,殭屍態 +:前臺程序 |:多執行緒程序 L:記憶體分頁並帶鎖 N:低優先順序程序 <:高優先順序程序 s:session leader,會話 (子程序)發起者
ps 優先順序選項和常用組合: ni:nice 值 pri:priority 優先順序,和系統優先順序相反 psr:processor CPU 編號,CPU(一級二級,三級[共享]快取) 更換 CPU 快取失效,解決:繫結程序和 CPU taskset -p [程序 ID],檢視,命令顯示和 CPU 核數不一樣[二進位制] tackset -cp 1 [程序 ID],繫結在 1 號 CPU 上 0,4 0-4 等 pidof dd,檢視 dd 命令的程序編號 rtprio:實時優先順序 # 示例: ps axo pid,cmd,psr,ni,pri,rtprio # 常用組合: aux -ef -eFH -eo pid,tid,class,rtprio,ni,pripsr,pcpu,stat,comm axo stat,euid,ruid,tty,tpgid,sess,pgrp,ppid,pid,pcpu,comm nice -n 10 ping 192.168.129.142 # 以指定優先順序執行該命令 renice # 更改優先順序
PS示例:
# 列出有效組名稱(或會話)所擁有的所有程序 ps -fg mysql ps -fg 27
# 顯示指定的程序 ID 對應的程序 ps -fp 1234
# 以父程序 ID 來顯示其下所有的程序,如顯示父程序為 1234 的所有程序 ps -f –ppid 1234
# 顯示指定 PID 的多個程序 ps -fp 1234,1236,1264
# 要按 tty 顯示所屬程序 ps -ft pts/0
# 自定義格式顯示檔案系統組,ni 值開始時間和程序的時間 ps -p 1234 -o pid,ppid,fgroup,ni,lstart,etime
# 使用其 PID 查詢程序名稱 ps -p 1234 -o comm=
# 要使用其名稱選擇特定程序,顯示其所有子程序 ps -C sshd,bash
# 查詢指定程序名所有的所屬 PID,在編寫需要從 std 輸出或檔案讀取 PID 的指令碼時這個引數很有用 ps -C httpd,sshd -o pid=
# 檢查一個程序的執行時間 ps -eo comm,etime,user | grep nginx
# 查詢佔用最多記憶體和 CPU 的程序 ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%mem | head ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%cpu | head
# 顯示安全資訊 ps-eM ps --context
# 使用以下命令以使用者定義的格式顯示安全資訊 ps -eo euser,ruser,suser,fuser,f,comm,label
# 使用 watch 實用程式執行重複的輸出以實現對就程進行實時的監視,如下面的命令顯示每秒鐘的監視 watch -n 1 'ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%mem| head'
搜素程序:
最靈活:ps 選項 | 其它命令 按預定義的模式:pgrep pgrep [options] pattern -u uid: effective user,生效者 -U uid: realuser,真正發起執行命令者 -t terminal:與指定終端相關的程序 pgrep -t pts/1 -l:顯示程序名 -a:顯示完整格式的程序名 -P pid:顯示指定程序的子程序
按確切的程式名稱查詢程序 ID: /sbin/pidof pidof bash
9.3 top 詳解
top:有許多內建命令 排序: P:以佔據的 CPU 百分比,%CPU M:佔據記憶體百分比,%MEM T:累積佔據 CPU 時長,TIME+
首部資訊顯示: uptime 資訊: |命令 tasks 及 cpu 資訊: t 命令 cpu 分別顯示: 1 (數字) memory 資訊: m 命令 退出命令: q 修改重新整理時間間隔: s 終止指定程序: k 儲存檔案: W
欄位資訊簡介 us:使用者空間 sy:核心空間 ni:調整 nice 時間 id:空閒 wa:等待 IO 時間 hi:硬中斷 si:軟中斷(模式切換) st:虛擬機器偷走的時間
選項: -d # 指定重新整理時間間隔,預設為 3 秒 -b 全部顯示所有程序 -n # 重新整理多少次後退出 -H 執行緒模式,示例:top -H -p `pidof mysqld`
9.4 htop 詳解
htop 命令:EPEL 源 選項: -d #:指定延遲時間; -u UserName:僅顯示指定使用者的程序 -s COLUME:以指定欄位進行排序
子命令: s:跟蹤選定程序的系統呼叫 |:顯示選定程序開啟的檔案列表 a:將選定的程序繫結至某指定 CPU 核心 t:顯示程序樹
10、記憶體管理工具
10.1 free 命令詳解
記憶體空間使用狀態: free [OPTION] -b 以位元組為單位 -m 以 MB 為單位 -g 以 GB 為單位 -h 易讀格式 -0 不顯示-/+ buffers/cache 行 -t 顯示 RAM + swap 的總和 -s n 重新整理間隔為 n 秒 -c n 重新整理 n 次後即退出 cat /proc/sys/vm/drop_caches # 快取為 0,重定向一個 3 進去清理快取
10.2 記憶體工具 vmstat
vmstat 命令:虛擬記憶體資訊 vmstat [options] [delay [count]] vmstat 2 5 # 2 秒執行一次,執行 5 次退出
procs: r:可執行(正執行或等待執行)程序的個數,和核心數有關 b:處於不可中斷睡眠態的程序個數(被阻塞的佇列的長度) memory: swpd:交換記憶體的使用總量 free:空閒實體記憶體總量 buffer:用於 buffer 的記憶體總量 cache:用於 cache 的記憶體總量 swap: si:從磁碟交換進記憶體的資料速率(kb/s) so:從記憶體交換至磁碟的資料速率(kb/s) io: bi:從塊裝置讀入資料到系統的速率(kb/s) bo:儲存資料至塊裝置的速率 system: in:interrupts 中斷速率,包括時鐘 cs:context switch 程序切換速率 cpu: us:Time spent running non-kernel code sy:Time spent running kernel code id:Time spent idle. Linux 2.5.41 前,包括 IO-wait time. wa:Time spent waiting for IO.2.5.41 前 ,包括 in idle. st:Time stolen from a virtual machine. 2.6.11 前, unknown.
選項: -s:顯示記憶體的統計資料
11、iostat 統計CPU和裝置IO資訊
例: iostat 1 10
12、iftop 顯示頻寬使用情況,epel源
例: iftop -n -i eth1
13、pmap 命令:程序對應的記憶體對映
pmap [options] pid [..] -X:顯示詳細格式的資訊 例: pmap1
14、系統監控工具
glances 命令: EPEL 源
glances [-bdehmnrsvyz1] [-B bind] [-c server] [-C conffile] [-p port] [-P password] [--password] [-t refresh] [-f file] [-o output] 內建命令: a – 對程序自動排序
c – 按 CPU 百分比對程序排序
m – 按記憶體百分比對程序排序
p – 按程序名字母順序對程序排序
i – 按讀寫頻率(I/O)對程序排序
d – 顯示/隱藏磁碟 I/O 統計資訊
f – 顯示/隱藏檔案系統統計資訊
n – 顯示/隱藏網路介面統計資訊
s – 顯示/隱藏感測器統計資訊
y – 顯示/隱藏硬碟溫度統計資訊
l – 顯示/隱藏日誌(log)
b – 切換網路 I/O 單位(Bytes/bits)
w – 刪除警告日誌
x – 刪除警告和嚴重日誌
l – 切換全域性 CPU 使用情況和每個 CPU 的使用情況
h – 顯示/隱藏這個幫助畫面
t – 以組合形式瀏覽網路 I/O
u – 以累計形式瀏覽網路 I/O
q – 退出('ESC' 和 'Ctrl&C' 也可以)
常用選項: -b:以 Byte 為單位顯示網絡卡資料速率 -d:關閉磁碟 I/O 模組 -f /path/to/somefile:設定輸入檔案位置 -o {HTML|CSV} :輸出格式 -m:禁用 mount 模組 -n:禁用網路模組 -t #:延遲時間間隔 -1 :每個 CPU 的相關資料單獨顯示
C/S 模式下執行 glances 命令 伺服器模式: glances -s -B IPADDR IPADDR:指明監聽的本機哪個地址 客戶端模式: glances -c IPADDR IPADDR:要連入的伺服器端地址
dstat 命令詳解:系統資源統計
dstat 是一個可以取代vmstat,iostat,netstat和ifstat這些命令的多功能產品。
# yum install dsta //安裝 dstat [-afv] [options..] [delay [count] 常用命令選項: -c, --cpu:顯示cpu相關資訊; -C #,#,...,total -d, --disk:顯示磁碟的相關資訊 -D sda,sdb,...,tobal -g:顯示page相關的速率資料; -m:Memory的相關統計資料 -n:Interface的相關統計資料; -p:顯示process的相關統計資料; -r:顯示io請求的相關的統計資料; -s:顯示swapped的相關統計資料; --tcp --udp --raw --socket --ipc --top-cpu:顯示最佔用CPU的程序; --top-io:最佔用io的程序; --top-mem:最佔用記憶體的程序; --top-latency:延遲最大的程序;
示例1:記憶體資源使用情況
# dstat -glms --top-mem
示例2:CPU資源使用情況
# dstat -cyl --proc-count --top-cpu
iotop 命令詳解:
iotop 命令是一個用來監視磁碟 I/O 使用狀況的 top 類工具 iotop 具有與 top 相似的 UI,其中包括 PID、使用者、I/O、程序等相關資訊,可檢視每個程序是如何使用 IO iotop 輸出: 第一行:Read 和 Write 速率總計 第二行:實際的 Read 和 Write 速率 第三行:引數如下: 執行緒 ID (按 p 切換為程序 ID ) 優先順序 使用者 磁碟讀速率 磁碟寫速率 swap 交換百分比 IO 等待所佔的百分比 執行緒/程序命令
iotop 常用引數: -o,--only 只顯示正在產生I/O的程序或執行緒,除了傳參,可以在執行過程中按o生效 -b,--batch 非互動模式,一般用來記錄日誌 -n NUM,--iter=NUM 設定監測的次數,預設無限。在非互動模式下很有用 -d SEC,--delay=SEC 設定每次監測的間隔,預設1秒,接受非整形資料例如1.1 -p PID,--pid=PID 指定監測的程序/執行緒 -u USER,--user=USER 指定監測某個使用者產生的I/O -P,--processes 僅顯示程序,預設iotop顯示所有執行緒 -a,--accumulated 顯示累積的I/O,而不是頻寬 -k,--kilobytes 使用kb單位,而不是對人友好的單位。在非互動模式下,指令碼程式設計有用
iotop 常用引數和快捷鍵:
-t,--time 加上時間戳,非互動非模式
-q, --quiet 禁止頭幾行,非互動模式,有三種指定方式
-q 只在第一 次監測時顯示列名
-qq 永遠不顯示列名
-qqq 永遠不顯示I/0彙總
互動按鍵:
left 和 right 方向鍵:改變排序
r:反向排序
0:切換至選項--only
p:切換至--processes選項
a:切換至--accumulated選項
q:退出
i:改變執行緒的優先順序
nload 檢視網路實時吞吐量:
nload 是一個實時監控網路流量和頻寬使用情況,以數值和動態圖展示進出的流量情況
安裝:yum -y install nload (EPEL 源) 介面操作: 上下方向鍵、左右方向鍵、enter 鍵或者 tab 鍵都就可以切換檢視多個網絡卡的流量情況 按 F2 顯示選項視窗 按 q 或者 Ctrl+C 退出 nload
示例: nload:預設只檢視第一個網路的流量進出情況 nload eth0 eth1:在 nload 後面指定網絡卡,可以指定多個 設定重新整理間隔:預設重新整理間隔是 100 毫秒,可通過-t 命令設定重新整理時間(單位是毫秒) nload -t 500 eth0 設定單位:顯示兩種單位一種是顯示 Bit/s、一種是顯示 Byte/s,預設是以 Bit/s,也可不顯示/s -u h|b|k|m|g|H|B|K|M|G 表示的含義:h:auto,b:Bit/s,k:kBit/s,m:MBit/s,H:auto,B:Byte/s,K:kByte/s,M:MByte/s nload-u M eth0
lsof:list open files 檢視當前系統檔案的工具
在 linux 環境下,一切皆檔案,使用者通過檔案不僅可以訪問常規資料還可以訪問網路連線和硬體如傳輸控制協議(TCP)和使用者資料報協議(UDP)套接字等,系統在後臺都為該應用程式分配了一個檔案描述符 命令引數: -a:列出開啟檔案存在的程序 -c<程序名>:列出指定程序所開啟的檔案 -g:列出 GID 號程序詳情 -d<檔案號>:列出佔用該檔案號的程序 +d<目錄>:列出目錄下被開啟的檔案 +D<目錄>:遞迴列出目錄下被開啟的檔案
lsof示例:
程序管理:
檢視由登陸使用者啟動而非系統啟動的程序
lsof /dev/pts/1
指定程序號,可以檢視該程序開啟的檔案
Isof -p 9527
檔案管理:
檢視指定程式開啟的檔案
Isof -c httpd
檢視指定使用者開啟的檔案
Isof -u root | more
檢視指定目錄下被開啟的檔案
lsof +D /var/log/
lsof +d /var/log/
引數 +D 為遞迴列出目錄下被開啟的檔案,引數+d為列出目錄下被開啟的檔案
恢復刪除檔案:
lsof | grep delete # 檢視開啟檔案(被誤刪除),看到程序編號,如:11863
ll /proc/11863/fd # 檢視檔案描述符,如 4(已被刪除)
cat /proc/11863/fd/4 > /data/m.txt # 重定向找回檔案
檢視所有網路連線:
lsof -i -n
lsof [email protected]
通過引數 -i 檢視網路連線的情況,包括連線的ip、埠等以及一些服務的連線情況,例如:sshd等。也可以通過指定 ip 檢視該 ip 的網路連線情況。
檢視埠連線情況:
lsof -i :80 -n
通過引數 -i:埠 可以檢視埠的佔用情況,-i引數還有檢視協議,ip的連線情況等
檢視指定程序開啟的網路連線:
lsof -i -n -a -p 9527
引數-i、-a、-p等,-i檢視網路連線情況,-a檢視存在的程序,-p指定程序
檢視指定狀態的網路連線:
lsof -n -P -i TCP -s TCP:ESTABLISHED
-n:no host names,-P:no port names,-i TCP指定協議,-s指定協議狀態通過多個引數可以清晰的檢視網路連線情況、協議連線情況等
15、程序管理工具
kill 命令:向程序傳送控制訊號,以實現對程序管理每個訊號對應一個數字,訊號名稱以 SIG 開頭(可省略),不區分大小寫
顯示當前系統可用訊號:kill-I 或者 trap -l 常用訊號: man 7 signal 0) 訊號檢查某個程序是否正常 1) SIGHUP 無須關閉程序而讓其重讀配置檔案 2) SIGINT 中止正在執行的程序,相當於 Ctrl+C 3) SIGQUIT 相當於 ctrl+\ 9) SIGKILL 強制殺死正在執行的程序 15) SIGTERM 終止正在執行的程序,預設 18) SIGCONT 繼續執行 19) SIGSTOP 後臺休眠 指定訊號的方法: (1)訊號的數字標識:1,2,9 (2)訊號完整名稱:SIGHUP (3)訊號的簡寫名稱: HUP
示例: 先 ps aux 查到該程序 ID,kill -1 [程序 ID],發訊號 kill -2 `pidof bc` # 中止 bc 程式 按 PID:kill [-SIGNAL] pid ... kill -n SIGNAL pid kill -S SIGNAL pid 按名稱:killall [-SIGNAL] comm... # 例:killall httpd 按模式:pkill [options] pattern # 支援正則 -SIGNAL -u uid:effective user,生效者 -U uid:realuser,真正發起執行命令者 -t terminal:與指定終端相關的程序 -l:顯示程序名(pgrep 可用) -a:顯示完整格式的程序名(pgrep 可用) -P pid:顯示指定程序的子程序
16、作業管理
Linux 的作業控制:
前臺作業:通過終端啟動,且啟動後一直佔據終端
後臺作業:可通過終端啟動,但啟動後即轉入後臺執行(釋放終端)
讓作業運行於後臺:
(1)執行中的作業:Ctrl+z,停止狀態
(2)尚未啟動的作業:COMMAND &
後臺作業雖然被送往後臺執行,但其依然與終端相關;退出終端,將關閉後臺作業。如果希望送往後臺後,剝離與終端的關係:
nohup COMMAND &> /dev/null & screen ; COMMAND
檢視當前終端所有作業: jobs
作業控制:
fg [[%]JOB_NUM]:把指定的後臺作業調回前臺 bg [[%]JOB_ NUM]:讓送往後臺的作業在後臺繼續執行 kill [%JOB_ NUM]:終止指定的作業 killall -19 ping # 19 訊號將後臺變為後臺休眠狀態 killall -18 ping # 18 訊號將後臺休眠變為後臺執行
並行執行:同時執行多個程序,提高效率
方法 1: vi all.sh f1.sh& f2.sh& f3.sh&
方法 2: (f1.sh&);(f2.sh&);(f3.sh&)
方法 3: { f1.sh& f2.sh& f3.sh& } { ping 127.1& ping 127.2& ping 127.3& }
&n