Python中內(nèi)存監(jiān)控的三種實(shí)現(xiàn)方法介紹
在 Python 開發(fā)中,對(duì)內(nèi)存使用情況進(jìn)行監(jiān)控是一項(xiàng)至關(guān)重要的任務(wù)。無論是開發(fā)小型腳本還是大型應(yīng)用程序,不合理的內(nèi)存使用都可能導(dǎo)致性能下降,甚至引發(fā)程序崩潰。本文將詳細(xì)介紹幾種常見的 Python 內(nèi)存監(jiān)控方法,包括 psutil 庫(kù)、memory_profiler 庫(kù)以及 tracemalloc 模塊,并對(duì)它們進(jìn)行對(duì)比分析,同時(shí)說明各自的應(yīng)用場(chǎng)景。
1. 使用 psutil 庫(kù)監(jiān)控內(nèi)存
1.1 簡(jiǎn)介與安裝
psutil(Process and System Utilities)是一個(gè)跨平臺(tái)的庫(kù),它提供了豐富的系統(tǒng)信息獲取功能,包括 CPU、內(nèi)存、磁盤、網(wǎng)絡(luò)等。借助 psutil,我們可以方便地監(jiān)控系統(tǒng)和進(jìn)程的內(nèi)存使用情況。
安裝 psutil 非常簡(jiǎn)單,只需在命令行中運(yùn)行以下命令:
pip install psutil
1.2 示例代碼與功能實(shí)現(xiàn)
import psutil # 獲取系統(tǒng)的內(nèi)存使用情況 def get_system_memory_usage(): """ 獲取并打印系統(tǒng)的內(nèi)存使用情況。 該函數(shù)使用psutil庫(kù)來獲取系統(tǒng)的虛擬內(nèi)存信息,包括總內(nèi)存、已使用內(nèi)存、空閑內(nèi)存和內(nèi)存使用率。 所有內(nèi)存值都轉(zhuǎn)換為GB并保留兩位小數(shù)。 """ memory = psutil.virtual_memory() total = memory.total / (1024 ** 3) # 轉(zhuǎn)換為 GB used = memory.used / (1024 ** 3) # 轉(zhuǎn)換為 GB free = memory.free / (1024 ** 3) # 轉(zhuǎn)換為 GB percent = memory.percent print(f"總內(nèi)存: {total:.2f} GB") print(f"已使用內(nèi)存: {used:.2f} GB") print(f"空閑內(nèi)存: {free:.2f} GB") print(f"內(nèi)存使用率: {percent}%") # 獲取當(dāng)前進(jìn)程的內(nèi)存使用情況 def get_process_memory_usage(): """ 獲取并打印當(dāng)前進(jìn)程的內(nèi)存使用情況。 該函數(shù)使用psutil庫(kù)來獲取當(dāng)前進(jìn)程的內(nèi)存信息,具體是駐留集大小(RSS),并將其轉(zhuǎn)換為MB并保留兩位小數(shù)。 """ process = psutil.Process() memory_info = process.memory_info() rss = memory_info.rss / (1024 ** 2) # 轉(zhuǎn)換為 MB print(f"當(dāng)前進(jìn)程的駐留集大?。≧SS): {rss:.2f} MB") if __name__ == "__main__": """ 主程序入口。 當(dāng)腳本直接運(yùn)行時(shí),調(diào)用get_system_memory_usage和get_process_memory_usage函數(shù)來獲取并打印系統(tǒng)和當(dāng)前進(jìn)程的內(nèi)存使用情況。 """ print("系統(tǒng)內(nèi)存使用情況:") get_system_memory_usage() print("\n當(dāng)前進(jìn)程內(nèi)存使用情況:") get_process_memory_usage()
在上述代碼中,get_system_memory_usage 函數(shù)通過 psutil.virtual_memory() 獲取系統(tǒng)的內(nèi)存信息,包括總內(nèi)存、已使用內(nèi)存、空閑內(nèi)存和內(nèi)存使用率。get_process_memory_usage 函數(shù)則使用 psutil.Process() 獲取當(dāng)前進(jìn)程,并通過 memory_info() 方法獲取進(jìn)程的內(nèi)存信息,這里主要關(guān)注駐留集大?。≧SS),也就是當(dāng)前進(jìn)程的內(nèi)存消耗。
執(zhí)行結(jié)果如下:
C:\Users\gyfin\.conda\envs\pa001\python.exe D:\pyproject\pa001\AAP01\test6.py
系統(tǒng)內(nèi)存使用情況:
總內(nèi)存: 7.92 GB
已使用內(nèi)存: 6.32 GB
空閑內(nèi)存: 1.60 GB
內(nèi)存使用率: 79.8%
當(dāng)前進(jìn)程內(nèi)存使用情況:
當(dāng)前進(jìn)程的駐留集大?。≧SS): 15.12 MB
進(jìn)程已結(jié)束,退出代碼為 0
1.3 應(yīng)用場(chǎng)景
系統(tǒng)級(jí)監(jiān)控:當(dāng)你需要對(duì)整個(gè)系統(tǒng)的內(nèi)存使用情況進(jìn)行監(jiān)控時(shí),psutil 是一個(gè)很好的選擇。例如,在服務(wù)器環(huán)境中,定期監(jiān)控系統(tǒng)內(nèi)存使用情況,以便及時(shí)發(fā)現(xiàn)內(nèi)存不足的問題并采取相應(yīng)的措施,如優(yōu)化程序或增加物理內(nèi)存。
進(jìn)程級(jí)監(jiān)控:對(duì)于多進(jìn)程的 Python 應(yīng)用程序,你可以使用 psutil 監(jiān)控每個(gè)進(jìn)程的內(nèi)存使用情況,找出內(nèi)存占用過高的進(jìn)程,進(jìn)行針對(duì)性的優(yōu)化。
2. 使用 memory_profiler 庫(kù)監(jiān)控內(nèi)存
2.1 簡(jiǎn)介與安裝
memory_profiler 是一個(gè)專門用于監(jiān)控 Python 函數(shù)內(nèi)存使用情況的庫(kù)。它可以逐行分析函數(shù)的內(nèi)存使用情況,幫助我們精確地找出內(nèi)存分配的關(guān)鍵代碼行。
安裝 memory_profiler 同樣可以使用 pip 命令:
pip install memory_profiler
2.2 示例代碼與功能實(shí)現(xiàn)
from memory_profiler import profile # 使用memory_profiler庫(kù)的profile裝飾器來監(jiān)控函數(shù)的內(nèi)存使用情況 @profile def test_function(): """ 測(cè)試函數(shù),用于生成一個(gè)包含100萬個(gè)整數(shù)的列表,并在使用后刪除該列表。 該函數(shù)使用列表推導(dǎo)式生成一個(gè)包含100萬個(gè)整數(shù)的列表,然后刪除該列表以釋放內(nèi)存。 """ # 使用列表推導(dǎo)式生成一個(gè)包含100萬個(gè)整數(shù)的列表 data = [i for i in range(1000000)] # 刪除列表以釋放內(nèi)存 del data # 函數(shù)返回 return if __name__ == "__main__": """ 主程序入口。 當(dāng)腳本直接運(yùn)行時(shí),調(diào)用test_function函數(shù)來測(cè)試內(nèi)存使用情況。 """ # 調(diào)用test_function函數(shù) test_function()
在上述代碼中,我們使用 @profile 裝飾器來標(biāo)記需要監(jiān)控的函數(shù) test_function。需要注意的是,運(yùn)行該代碼時(shí),需要使用 python -m memory_profiler your_script.py 命令,這樣才能看到詳細(xì)的內(nèi)存使用分析。
程序執(zhí)行結(jié)果如下:
(pa001) D:\pyproject\pa001\AAP01>python -m memory_profiler test6.py
Filename: test6.py
Line # Mem usage Increment Occurrences Line Contents
=============================================================
3 50.1 MiB 50.1 MiB 1 @profile
4 def test_function():
5 88.5 MiB 35.0 MiB 1000003 data = [i for i in range(1000000)]
6 50.8 MiB -37.7 MiB 1 del data
7 50.8 MiB 0.0 MiB 1 return
2.3 應(yīng)用場(chǎng)景
函數(shù)級(jí)內(nèi)存分析:當(dāng)你懷疑某個(gè)函數(shù)存在內(nèi)存泄漏或內(nèi)存使用不合理的問題時(shí),memory_profiler 可以幫助你逐行分析該函數(shù)的內(nèi)存使用情況,找出內(nèi)存分配和釋放的關(guān)鍵代碼行,從而進(jìn)行針對(duì)性的優(yōu)化。
算法優(yōu)化:在開發(fā)算法時(shí),你可以使用 memory_profiler 監(jiān)控不同算法實(shí)現(xiàn)的內(nèi)存使用情況,選擇內(nèi)存效率更高的算法。
3. 使用 tracemalloc 模塊監(jiān)控內(nèi)存
3.1 簡(jiǎn)介與使用
tracemalloc 是 Python 標(biāo)準(zhǔn)庫(kù)中的一個(gè)模塊,可用于跟蹤內(nèi)存分配。它可以統(tǒng)計(jì)內(nèi)存分配的大小、數(shù)量,并找出內(nèi)存分配最多的代碼行。
3.2 示例代碼與功能實(shí)現(xiàn)
# 導(dǎo)入 tracemalloc 模塊,用于跟蹤內(nèi)存分配 import tracemalloc # 啟動(dòng) tracemalloc 跟蹤 tracemalloc.start() # 模擬一些內(nèi)存分配操作,創(chuàng)建一個(gè)包含100萬個(gè)整數(shù)的列表 data = [i for i in range(1000000)] # 獲取當(dāng)前內(nèi)存分配的快照 snapshot = tracemalloc.take_snapshot() # 統(tǒng)計(jì)內(nèi)存分配的前10個(gè)位置 top_stats = snapshot.statistics('lineno') # 打印標(biāo)題 print("[ Top 10 ]") # 遍歷并打印前10個(gè)內(nèi)存分配位置的統(tǒng)計(jì)信息 for stat in top_stats[:10]: print(stat) # 清理內(nèi)存,刪除列表 del data
在上述代碼中,tracemalloc.start() 用于啟動(dòng)內(nèi)存跟蹤,tracemalloc.take_snapshot() 用于獲取當(dāng)前的內(nèi)存分配快照,最后通過 snapshot.statistics('lineno') 可以按行統(tǒng)計(jì)內(nèi)存分配情況,并打印出內(nèi)存分配最多的前 10 行代碼的信息。
執(zhí)行結(jié)果如下:
C:\Users\gyfin\.conda\envs\pa001\python.exe D:\pyproject\pa001\AAP01\test7.py
[ Top 10 ]
D:\pyproject\pa001\AAP01\test7.py:6: size=38.6 MiB, count=999745, average=40 B
進(jìn)程已結(jié)束,退出代碼為 0
3.3 應(yīng)用場(chǎng)景
內(nèi)存泄漏檢測(cè):tracemalloc 可以幫助我們找出程序中可能存在的內(nèi)存泄漏問題。通過定期獲取內(nèi)存分配快照并進(jìn)行比較,我們可以發(fā)現(xiàn)哪些對(duì)象的內(nèi)存沒有被正確釋放,從而定位內(nèi)存泄漏的位置。
性能優(yōu)化:在優(yōu)化程序性能時(shí),我們可以使用 tracemalloc 找出內(nèi)存分配熱點(diǎn),即內(nèi)存分配最多的代碼行,然后對(duì)這些代碼進(jìn)行優(yōu)化,減少不必要的內(nèi)存分配。
4. 方法對(duì)比
4.1 功能對(duì)比
psutil 主要用于獲取系統(tǒng)和進(jìn)程的整體內(nèi)存使用情況,側(cè)重于宏觀層面的監(jiān)控。它可以方便地獲取系統(tǒng)總內(nèi)存、已使用內(nèi)存、空閑內(nèi)存以及進(jìn)程的駐留集大小等信息。
memory_profiler 專注于函數(shù)級(jí)別的內(nèi)存分析,能夠逐行顯示函數(shù)的內(nèi)存使用情況,幫助我們精確地找出內(nèi)存分配的關(guān)鍵代碼行。
tracemalloc 則側(cè)重于內(nèi)存分配的跟蹤和統(tǒng)計(jì),它可以統(tǒng)計(jì)內(nèi)存分配的大小、數(shù)量,并找出內(nèi)存分配最多的代碼行,對(duì)于檢測(cè)內(nèi)存泄漏和優(yōu)化內(nèi)存使用非常有幫助。
4.2 使用復(fù)雜度對(duì)比
psutil 的使用相對(duì)簡(jiǎn)單,只需要調(diào)用幾個(gè)簡(jiǎn)單的函數(shù)即可獲取系統(tǒng)和進(jìn)程的內(nèi)存信息。
memory_profiler 需要使用裝飾器來標(biāo)記需要監(jiān)控的函數(shù),并且運(yùn)行時(shí)需要使用特定的命令,使用起來稍微復(fù)雜一些。
tracemalloc 是 Python 標(biāo)準(zhǔn)庫(kù)的一部分,使用時(shí)只需要調(diào)用幾個(gè)函數(shù)即可啟動(dòng)和獲取內(nèi)存分配快照,但分析結(jié)果可能需要一定的經(jīng)驗(yàn)來解讀。
4.3 性能開銷對(duì)比
psutil 的性能開銷相對(duì)較小,因?yàn)樗饕菑南到y(tǒng)層面獲取內(nèi)存信息,不會(huì)對(duì)程序的正常運(yùn)行產(chǎn)生太大影響。
memory_profiler 的性能開銷相對(duì)較大,因?yàn)樗枰鹦蟹治龊瘮?shù)的內(nèi)存使用情況,會(huì)對(duì)程序的運(yùn)行速度產(chǎn)生一定的影響。
tracemalloc 的性能開銷也比較大,尤其是在內(nèi)存分配頻繁的情況下,因?yàn)樗枰櫭恳淮蝺?nèi)存分配操作。
總結(jié)
在 Python 中,psutil、memory_profiler 和 tracemalloc 都可以用于內(nèi)存監(jiān)控,但它們的功能和應(yīng)用場(chǎng)景有所不同。如果你需要監(jiān)控系統(tǒng)和進(jìn)程的整體內(nèi)存使用情況,建議使用 psutil;如果你需要對(duì)函數(shù)進(jìn)行逐行的內(nèi)存分析,memory_profiler 是一個(gè)不錯(cuò)的選擇;如果你需要檢測(cè)內(nèi)存泄漏和優(yōu)化內(nèi)存使用,tracemalloc 會(huì)更適合你。在實(shí)際應(yīng)用中,你可以根據(jù)具體的需求選擇合適的方法,或者結(jié)合使用多種方法來全面監(jiān)控和優(yōu)化程序的內(nèi)存使用情況。
到此這篇關(guān)于Python中內(nèi)存監(jiān)控的三種實(shí)現(xiàn)方法介紹的文章就介紹到這了,更多相關(guān)Python內(nèi)存監(jiān)控內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python在Windows和在Linux下調(diào)用動(dòng)態(tài)鏈接庫(kù)的教程
這篇文章主要介紹了Python在Windows和在Linux下調(diào)用動(dòng)態(tài)鏈接庫(kù)的教程,在進(jìn)行Python的CS端編程時(shí)經(jīng)常需要用到,需要的朋友可以參考下2015-08-08python dataframe常見操作方法:實(shí)現(xiàn)取行、列、切片、統(tǒng)計(jì)特征值
今天小編就為大家分享一篇python dataframe常見操作方法:實(shí)現(xiàn)取行、列、切片、統(tǒng)計(jì)特征值,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-06-06PyQt實(shí)現(xiàn)界面翻轉(zhuǎn)切換效果
這篇文章主要為大家詳細(xì)介紹了PyQt實(shí)現(xiàn)界面翻轉(zhuǎn)切換效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04python實(shí)現(xiàn)簡(jiǎn)單五子棋游戲
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)簡(jiǎn)單五子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-06-06Django Auth應(yīng)用實(shí)現(xiàn)用戶身份認(rèn)證
Django Auth 應(yīng)用一般用在用戶的登錄注冊(cè)上,用于判斷當(dāng)前的用戶是否合法。本文將介紹Auth的另一個(gè)功能,即認(rèn)證用戶身份,感興趣的同學(xué)可以關(guān)注一下2021-12-12Android Q之氣泡彈窗的實(shí)現(xiàn)示例
這篇文章主要介紹了Android Q之氣泡彈窗的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06