極客時間 - 《Linux 性能優化實戰》原文鏈接:https://time.geekbang.org/column/intro/100020901
- 02 | 基礎篇:到底應該怎么理解“平均負載”?
- 在Linux系統中,當一個進程啟動時,操作系統會為該進程申請哪些資源?(9點)
- 如何理解進程的 S 狀態?
- 如何理解進程的 D 狀態?
- 如何理解進程的 R 狀態?
- 如何理解進程的 Z 狀態?
- 如何理解父進程執行結束,操作系統也會釋放子僵尸進程描述符?
- 如何理解進程的 I 狀態?
- 如何理解進程的 T 狀態?
- 如何理解平均負載?
- 如何理解 uptime 的運行結果?如何判斷結果是否正常或異常?
- 如何理解CPU使用率?
- 如何理解CPU使用率和平均負載的關系?
- 如何理解 mpstat 工具?
- 如何理解 pidstat 工具?
- 03 | 基礎篇:經常說的 CPU 上下文切換是什么意思?(上)
- CPU中有哪些常見的寄存器,功能是什么?(9種)
- 進程的上下文切換都切換了哪些信息?(7條)
- CPU在什么情況下切換到其他進程運行?(6點)
- 同一進程內線程的上下文切換,哪些信息會切換?哪些信息不會切換?
- 會切換的信息(5條)
- 不會切換的信息(4條)
- 中斷的上下文切換,哪些信息會切換?哪些信息不會切換?
- 會切換的信息(4條)
- 不會切換的信息(3條)
- 04 | 基礎篇:經常說的 CPU 上下文切換是什么意思?(下)
- 如何理解 vmstat 工具?
- 如何理解 pidstat 工具查看線程上下文切換?
- 如何理解 cswch 和 nvcswch ?
- 如何查看中斷升高發生的類型?
- 什么情況的每秒上下文切換才算正常?
- 05 | 基礎篇:某個應用的CPU使用率居然達到100%,我該怎么辦?
- 如何理解 top 命令的運行結果?
- 如何理解 ps 命令的運行結果?
- 如何理解 平均CPU使用率?
- 如何理解CPU節拍率?
- 分析一下 man proc?
- 如何使用 perf 工具定位到 CPU占用率高的具體源碼行數?
02 | 基礎篇:到底應該怎么理解“平均負載”?
在Linux系統中,當一個進程啟動時,操作系統會為該進程申請哪些資源?(9點)
- PID:系統中唯一標識,用于區分不同的進程,進行進程管理和調度。
- 虛擬內存空間:包括代碼段、數據段、堆、棧等,存儲進程代碼、數據、運行時堆棧等信息。
- 文件描述符:進程可以打開文件、管道、套接字等,操作系統會為這些打開的資源分配文件描述符,用于標記和訪問這些資源。
- CPU時間片:確保進程能夠獲得必要的CPU資源來執行其任務。
- 進程控制塊 PCB:操作系統會為每個進程創建一個進程控制塊,其中包含進程的狀態信息、寄存器值、調度信息等,用于管理和調度進程。
- 環境變量:包含了一些配置信息和運行時參數,影響進程運行和配置。
- 信號處理器:操作系統會為進程設置信號處理器,用于處理各種信號事件(如中斷、終止信號等),確保進程能夠正確響應各種信號事件。
- 用戶和組ID,用于權限管理和訪問控制。
- 網絡資源:socket,支持進程進行網絡通信。
如何理解進程的 S 狀態?
- S(interruptible Sleep)
- 進入條件:需要等待可被信號中斷的事件發生。
- 可處理信號。
- 進程暫停執行,釋放CPU資源。
- 等待的特定事件發生后,從S狀態轉換為就緒狀態,等待CPU調度執行。
- 應用場景:文件IO,網絡通信,進程間通信。
如何理解進程的 D 狀態?
- D(Uninterruptible Sleep)
- 進入條件:需要等待可被信號中斷的事件發生。
- 不可處理信號,直到等待事件發生。(這個時候信號會等事件響應之后處理嗎?)
- 進程暫停執行,釋放CPU資源。
- 等待的特定事件發生后,從S狀態轉換為就緒狀態,等待CPU調度執行。
- 應用場景(進程與硬件設備直接交互):磁盤讀寫,DMA操作,內核鎖,內核同步操作。
如何理解進程的 R 狀態?
- R(Running):進程正在被CPU調度,占用CPU。
- R(Runnable):進程等待被CPU調度,不占用CPU。
如何理解進程的 Z 狀態?
- Z(Zombie)僵尸狀態。
- 子進程執行結束,子進程描述符保留在操作系統進程表中。
- 子進程不能通過發送信號殺死,需要通過父進程調用
wait()
或waitpid()
來獲取其退出狀態信息后,操作系統釋放進程描述符。 - 父進程執行結束,操作系統也會釋放子僵尸進程描述符。
- 不占用CPU和內存資源,占用進程表中的一個進程描述符。
如何理解父進程執行結束,操作系統也會釋放子僵尸進程描述符?
- 操作系統檢測到父進程結束。
- 將僵尸子進程PPID改為1,即 init 進程的PID。
- init進程會定期調用 wait() 或 waitpid() 系統調用來獲取僵尸子進程的退出狀態,操作系統釋放僵尸子進程資源(包括文件描述符),結束這些僵尸子進程的生命周期。
如何理解進程的 I 狀態?
如何理解進程的 T 狀態?
如何理解平均負載?
單位時間內,系統處于 R狀態(正在使用 CPU 或者正在等待 CPU 的進程) 和 D狀態(不可中斷睡眠狀態的進程) 的平均進程數。
如何理解 uptime 的運行結果?如何判斷結果是否正常或異常?
TUPIAN
$ uptime
02:34:03 up 2 days, 20:14, 1 user, load average: 0.63, 0.83, 0.88
正常情況:
- 平均負載數值 / CPU邏輯核心數 < 70%。
- 分析趨勢:1 分鐘、5 分鐘、15 分鐘的三個值基本相同,或者相差不大。
異常情況:
- 平均負載數值 / CPU邏輯核心數 > 70%。
- 分析趨勢:1 分鐘、5 分鐘、15 分鐘的三個值遞減,說明最近這段時間負載在增加,一旦 1 分鐘的平均負載接近或超過了邏輯 CPU 的個數,就意味著系統正在發生過載問題,需要分析問題并進行優化。
如何理解CPU使用率?
如何理解CPU使用率和平均負載的關系?
場景 | CPU使用率 | 平均負載 |
---|---|---|
CPU密集型進程 | ↑(CPU實際使用率會升高。) | ↑(正在使用CPU的進程數增加。) |
IO密集型 | —(IO操作不會占用CPU。) | ↑(等待IO,不可中斷睡眠狀態進程數增加。) |
大量等待CPU調度的進程 | ↑(大量進程在進行上下文切換,會消耗CPU,CPU并沒有在真正的執行進程指令。) | ↑(等待CPU調度的進程數增加。) |
如何理解 mpstat 工具?
功能:多核 CPU 性能分析工具,用來實時查看每個 CPU 的性能指標,以及所有 CPU 的平均指標。
執行結果分析:
如何理解 pidstat 工具?
功能:進程性能分析工具,用來實時查看進程的 CPU、內存、I/O 以及上下文切換等性能指標。
執行結果分析:
03 | 基礎篇:經常說的 CPU 上下文切換是什么意思?(上)
CPU中有哪些常見的寄存器,功能是什么?(9種)
- 通用寄存器(General Purpose Registers, GPRs):存儲數據和地址。
- 程序計數器(Program Counter):存儲下一條要執行的指令的地址。
- 棧寄存器(Stack Pointer, SP):指向當前棧的頂部。
- 基址指針(Base Pointer, BP):指向棧中的某個固定地址(通常是函數的棧起始地址),通過 基址指針 + 偏移 訪問局部變量和參數。
- 指令寄存器(Instruction Register):存儲當前正在執行的指令。
- 狀態寄存器(Status Register):存儲CPU執行指令后的狀態信息,如進位標志(CF)、零標志(ZF)、符號標志(SF)、溢出標志(OF)等。
- 浮點寄存器:用于存儲浮點數和SIMD(單指令多數據)指令的數據。
- 控制寄存器:存儲CPU的控制信息,如分頁機制、保護模式、調試等。
- 調試寄存器:用于硬件調試,如設置斷點、監視內存訪問等。
進程的上下文切換都切換了哪些信息?(7條)
- 所有寄存器信息。
- 虛擬內存信息。
- 進程狀態。(就緒,等待,運行等)
- 進程優先級。
- IO狀態信息:IO緩沖區、文件打開狀態等。
- 資源使用情況。(CPU使用時間,內存使用情況等)
- 信號處理相關信息。(待處理的信號列表,信號處理函數地址等)
CPU在什么情況下切換到其他進程運行?(6點)
- 分片的時間片用完。
- 當前進程執行結束。
- 程序主動 sleep。
- 資源不足(例如:內存)。
- 硬件中斷,執行內核中斷服務程序。
- 高優先級進程運行存在時。
同一進程內線程的上下文切換,哪些信息會切換?哪些信息不會切換?
會切換的信息(5條)
- 程序計數器(Program Counter):保存當前線程下一條要執行的指令的地址。
- 寄存器狀態:包括通用寄存器、浮點寄存器、狀態寄存器等所有CPU寄存器的內容。
- 棧指針和基址指針:保存當前線程棧頂和棧起始位置。
- 線程狀態:運行、就緒、阻塞等狀態。
- 線程本地存儲:保存線程私有數據。
不會切換的信息(4條)
- 進程虛擬地址空間:同一進程內所有線程共享相同的虛擬地址空間(代碼段、數據段、堆等)。
- 全局變量和靜態變量:進程的虛擬地址空間共享。
- 打開的文件描述符和文件系統信息:進程級別資源。
- 信號處理設置。
中斷的上下文切換,哪些信息會切換?哪些信息不會切換?
會切換的信息(4條)
- 通用寄存器。
- 程序計數器(Program Counter):存儲下一條要執行的指令的地址。
- 棧寄存器(Stack Pointer, SP):指向當前棧的頂部。
- 狀態寄存器(Status Register):存儲CPU執行指令后的狀態信息,如進位標志(CF)、零標志(ZF)、符號標志(SF)、溢出標志(OF)等。
不會切換的信息(3條)
- 內存內容:內存中的數據通常不會因為中斷而切換,除非中斷處理程序需要修改這些數據。
- 外部設備狀態:外部設備的狀態(如硬盤、網絡接口等)不會因為中斷而切換,這些狀態由設備自身管理。
- 全局變量和靜態變量:這些變量的值通常不會因為中斷而切換,除非中斷處理程序需要修改這些變量。
04 | 基礎篇:經常說的 CPU 上下文切換是什么意思?(下)
如何理解 vmstat 工具?
功能:
執行結果分析:
如何理解 pidstat 工具查看線程上下文切換?
功能:pidstat -wt 1
執行結果分析:
如何理解 cswch 和 nvcswch ?
cswch(每秒自愿上下文切換(voluntary context switches)的次數):系統資源不足發生。
cswch變多,進程都在等待資源,有可能發生了 I/O 等其他問題;
nvcswch(每秒非自愿上下文切換(non voluntary context switches)的次數):時間片用完,系統強制調度。
nvcswch變多,進程都在被強制調度,也就是都在爭搶 CPU,說明 CPU 的確成了瓶頸;
如何查看中斷升高發生的類型?
功能:watch -d cat /proc/interrupts
interrupt變多, CPU 被中斷處理程序占用,需要通過查看 /proc/interrupts 文件來分析具體的中斷類型。
什么情況的每秒上下文切換才算正常?
- 穩定在1萬次以內。
- 有增長,但是次數不是數量級的增長。
05 | 基礎篇:某個應用的CPU使用率居然達到100%,我該怎么辦?
如何理解 top 命令的運行結果?
如何理解 ps 命令的運行結果?
如何理解 平均CPU使用率?
TUPIAN:公式
如何理解CPU節拍率?
CPU節拍率:CPU每秒發生時鐘中斷的次數,如果是100,則CPU每秒發生100次時鐘中斷。
每次時鐘中斷的發生,操作系統都有機會進行上下文切換,實現多個任務共享CPU時間,實現多任務并發處理。