Python如何監(jiān)控并獲取內(nèi)存使用情況
在Python開(kāi)發(fā)中,監(jiān)控內(nèi)存使用情況對(duì)于性能優(yōu)化、資源管理和問(wèn)題排查至關(guān)重要。本文將介紹多種獲取內(nèi)存使用情況的方法,涵蓋操作系統(tǒng)級(jí)監(jiān)控、Python對(duì)象內(nèi)存分析以及第三方工具的使用。
一、為什么需要監(jiān)控內(nèi)存使用
- 性能優(yōu)化:識(shí)別內(nèi)存泄漏或過(guò)度內(nèi)存消耗
- 資源管理:在容器化環(huán)境中控制資源使用
- 問(wèn)題排查:分析內(nèi)存異常增長(zhǎng)的原因
- 容量規(guī)劃:為系統(tǒng)擴(kuò)展提供數(shù)據(jù)支持
二、操作系統(tǒng)級(jí)內(nèi)存監(jiān)控
方法1:使用psutil庫(kù)(跨平臺(tái)推薦)
psutil是一個(gè)跨平臺(tái)庫(kù),可以輕松獲取系統(tǒng)內(nèi)存信息:
import psutil
def get_system_memory_info():
"""獲取系統(tǒng)內(nèi)存使用情況"""
mem = psutil.virtual_memory()
swap = psutil.swap_memory()
print("=== 系統(tǒng)內(nèi)存信息 ===")
print(f"總內(nèi)存: {mem.total / (1024**3):.2f} GB")
print(f"可用內(nèi)存: {mem.available / (1024**3):.2f} GB")
print(f"已用內(nèi)存: {mem.used / (1024**3):.2f} GB")
print(f"內(nèi)存使用率: {mem.percent}%")
print("\n=== 交換分區(qū)信息 ===")
print(f"總交換空間: {swap.total / (1024**3):.2f} GB")
print(f"已用交換空間: {swap.used / (1024**3):.2f} GB")
print(f"交換空間使用率: {swap.percent}%")
# 使用示例
get_system_memory_info()
方法2:讀取/proc/meminfo(Linux專用)
在Linux系統(tǒng)中,可以直接讀取/proc/meminfo文件:
def get_linux_memory_info():
"""Linux系統(tǒng)內(nèi)存信息(通過(guò)/proc/meminfo)"""
try:
with open('/proc/meminfo', 'r') as f:
mem_info = {}
for line in f:
parts = line.split(':')
if len(parts) == 2:
key = parts[0].strip()
value = int(parts[1].split()[0]) # 取第一個(gè)數(shù)值
mem_info[key] = value
# 轉(zhuǎn)換為GB單位
total = mem_info['MemTotal'] / (1024**2)
available = mem_info['MemAvailable'] / (1024**2) if 'MemAvailable' in mem_info else 0
used = total - available
print("=== Linux內(nèi)存信息 ===")
print(f"總內(nèi)存: {total:.2f} GB")
print(f"可用內(nèi)存: {available:.2f} GB")
print(f"已用內(nèi)存: {used:.2f} GB")
print(f"內(nèi)存使用率: {(used/total)*100:.1f}%")
except FileNotFoundError:
print("無(wú)法讀取/proc/meminfo(非Linux系統(tǒng))")
# 使用示例
get_linux_memory_info()
方法3:使用resource模塊(Unix系統(tǒng))
Python內(nèi)置的resource模塊可以獲取當(dāng)前進(jìn)程的內(nèi)存使用:
import resource
def get_process_memory_unix():
"""獲取當(dāng)前進(jìn)程的內(nèi)存使用(Unix系統(tǒng))"""
try:
# 獲取最大駐留集大?。≧SS)
rss = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
# 單位轉(zhuǎn)換(不同系統(tǒng)單位不同)
if hasattr(resource, 'getpagesize'):
page_size = resource.getpagesize()
rss_gb = rss * page_size / (1024**3)
else:
# 假設(shè)單位是KB(常見(jiàn)于Linux)
rss_gb = rss / (1024**2)
print(f"當(dāng)前進(jìn)程內(nèi)存使用: {rss_gb:.2f} GB")
except AttributeError:
print("resource模塊功能在當(dāng)前系統(tǒng)不可用")
# 使用示例
get_process_memory_unix()
三、Python對(duì)象內(nèi)存分析
方法1:使用sys.getsizeof()
獲取單個(gè)Python對(duì)象的大?。ㄗ⒁猓翰话瑢?duì)象引用的其他對(duì)象):
import sys
def object_memory_example():
"""演示sys.getsizeof()的使用"""
print("基本類型內(nèi)存占用:")
print(f"int: {sys.getsizeof(42)} bytes")
print(f"float: {sys.getsizeof(3.14)} bytes")
print(f"str: {sys.getsizeof('hello')} bytes")
print(f"list: {sys.getsizeof([1, 2, 3])} bytes")
print(f"dict: {sys.getsizeof({'a': 1})} bytes")
# 使用示例
object_memory_example()
方法2:使用pympler庫(kù)(深度分析)
pympler提供了更全面的內(nèi)存分析工具:
from pympler import asizeof, summary, muppy
def deep_memory_analysis():
"""深度內(nèi)存分析示例"""
# 創(chuàng)建一些測(cè)試對(duì)象
test_data = {
'list': [i for i in range(1000)],
'dict': {i: str(i) for i in range(1000)},
'set': set(range(1000)),
'str': 'a' * 10000
}
# 獲取單個(gè)對(duì)象大小
print(f"列表大小: {asizeof.asizeof(test_data['list'])/1024:.2f} KB")
# 獲取所有對(duì)象的匯總信息
all_objects = muppy.get_objects()
sum_obj = summary.summarize(all_objects)
summary.print_(sum_obj)
# 獲取特定類型對(duì)象的匯總
from pympler.class_tracker import ClassTracker
tracker = ClassTracker()
tracker.track_object(test_data)
tracker.create_snapshot()
tracker.stats.print_()
# 使用示例(注釋掉以避免輸出過(guò)長(zhǎng))
# deep_memory_analysis()
方法3:跟蹤內(nèi)存變化
import tracemalloc
def track_memory_usage():
"""跟蹤內(nèi)存分配變化"""
tracemalloc.start()
# 第一次快照
snapshot1 = tracemalloc.take_snapshot()
# 執(zhí)行一些內(nèi)存分配操作
data = [i for i in range(100000)]
# 第二次快照
snapshot2 = tracemalloc.take_snapshot()
# 比較兩個(gè)快照
top_stats = snapshot2.compare_to(snapshot1, 'lineno')
print("[ Top 10 memory growth ]")
for stat in top_stats[:10]:
print(stat)
tracemalloc.stop()
# 使用示例
track_memory_usage()
四、實(shí)時(shí)監(jiān)控內(nèi)存使用
方法1:使用memory_profiler
# 需要先安裝: pip install memory_profiler
from memory_profiler import memory_usage
import time
def my_function():
"""測(cè)試函數(shù)內(nèi)存使用"""
data = [i for i in range(100000)]
time.sleep(1)
return sum(data)
# 監(jiān)控函數(shù)內(nèi)存使用
mem_usage = memory_usage((my_function, (), {}), interval=0.1)
print(f"最大內(nèi)存使用: {max(mem_usage):.2f} MB")
方法2:裝飾器方式監(jiān)控
from memory_profiler import profile
@profile
def memory_intensive_function():
"""使用裝飾器監(jiān)控內(nèi)存"""
a = [1] * (10 ** 6)
b = [2] * (2 * 10 ** 7)
del b
return a
# 使用示例(運(yùn)行時(shí)會(huì)輸出內(nèi)存使用報(bào)告)
# memory_intensive_function()
五、不同場(chǎng)景下的最佳實(shí)踐
1. Web應(yīng)用內(nèi)存監(jiān)控
# 在Flask應(yīng)用中監(jiān)控內(nèi)存
from flask import Flask
import psutil
import os
app = Flask(__name__)
@app.route('/memory')
def check_memory():
process = psutil.Process(os.getpid())
mem_info = process.memory_info()
return {
'rss': f"{mem_info.rss / (1024**2):.2f} MB", # 駐留集大小
'vms': f"{mem_info.vms / (1024**2):.2f} MB", # 虛擬內(nèi)存大小
'percent': f"{process.memory_percent():.1f}%"
}
2. 數(shù)據(jù)處理任務(wù)監(jiān)控
import pandas as pd
import numpy as np
from memory_profiler import memory_usage
def process_large_data():
def inner():
df = pd.DataFrame(np.random.rand(10000, 1000))
return df.sum().sum()
mem_usage = memory_usage((inner, (), {}))
print(f"數(shù)據(jù)處理最大內(nèi)存使用: {max(mem_usage):.2f} MB")
process_large_data()
3. 長(zhǎng)期運(yùn)行服務(wù)的監(jiān)控
import time
import psutil
def monitor_memory_loop(interval=60):
"""定期監(jiān)控內(nèi)存使用"""
while True:
mem = psutil.virtual_memory()
print(f"[{time.ctime()}] 內(nèi)存使用: {mem.percent}%")
time.sleep(interval)
# 在生產(chǎn)環(huán)境中建議使用日志記錄而非print
# monitor_memory_loop()
六、注意事項(xiàng)
單位轉(zhuǎn)換:注意不同API返回的單位可能是字節(jié)、KB或MB
共享內(nèi)存:某些工具計(jì)算的內(nèi)存可能包含共享庫(kù)占用的內(nèi)存
GC影響:Python的垃圾回收機(jī)制會(huì)影響內(nèi)存測(cè)量結(jié)果
容器環(huán)境:在Docker等容器中,需要使用cgroup感知的工具
多線程:多線程環(huán)境下內(nèi)存測(cè)量可能不準(zhǔn)確
七、總結(jié)
| 方法 | 適用場(chǎng)景 | 特點(diǎn) |
|---|---|---|
| psutil | 系統(tǒng)級(jí)監(jiān)控 | 跨平臺(tái),信息全面 |
| /proc/meminfo | Linux系統(tǒng) | 直接讀取內(nèi)核信息 |
| sys.getsizeof() | 對(duì)象大小 | 簡(jiǎn)單快速,但不遞歸 |
| pympler | 深度分析 | 提供對(duì)象關(guān)系和變化跟蹤 |
| memory_profiler | 函數(shù)級(jí)監(jiān)控 | 裝飾器方式,適合開(kāi)發(fā)調(diào)試 |
| tracemalloc | 內(nèi)存變化跟蹤 | Python內(nèi)置,無(wú)需安裝 |
根據(jù)具體需求選擇合適的方法:
- 系統(tǒng)級(jí)監(jiān)控推薦
psutil - 開(kāi)發(fā)調(diào)試推薦
memory_profiler或pympler - 生產(chǎn)環(huán)境監(jiān)控建議結(jié)合系統(tǒng)工具和自定義日志
通過(guò)合理使用這些工具,可以有效地監(jiān)控和管理Python應(yīng)用的內(nèi)存使用情況。
到此這篇關(guān)于Python如何監(jiān)控并獲取內(nèi)存使用情況的文章就介紹到這了,更多相關(guān)Python獲取內(nèi)存使用情況內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Python獲取字典變量?jī)?nèi)存占用的四種方法
- Python獲取android設(shè)備cpu和內(nèi)存占用情況
- python獲取系統(tǒng)內(nèi)存占用信息的實(shí)例方法
- python在linux系統(tǒng)下獲取系統(tǒng)內(nèi)存使用情況的方法
- linux系統(tǒng)使用python獲取內(nèi)存使用信息腳本分享
- Python中內(nèi)存監(jiān)控的三種實(shí)現(xiàn)方法介紹
- Python實(shí)現(xiàn)監(jiān)控內(nèi)存使用情況和代碼執(zhí)行時(shí)間
- python 監(jiān)控某個(gè)進(jìn)程內(nèi)存的情況問(wèn)題
相關(guān)文章
使用Dajngo 通過(guò)代碼添加xadmin用戶和權(quán)限(組)
這篇文章主要介紹了使用Dajngo 通過(guò)代碼添加xadmin用戶和權(quán)限(組),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-07-07
Python的元組和字典知識(shí)點(diǎn)超詳細(xì)講解
這篇文章主要介紹了Python中元組和字典兩種數(shù)據(jù)結(jié)構(gòu)的基本用法,包括初始化、索引、拼接、剔除、重復(fù)、最大值和最小值、鍵值查詢、獲取對(duì)應(yīng)值、剔除、更新、添加和計(jì)算數(shù)量等操作,需要的朋友可以參考下2025-01-01
python動(dòng)態(tài)參數(shù)用法實(shí)例分析
這篇文章主要介紹了python動(dòng)態(tài)參數(shù)用法,以實(shí)例形式較為詳細(xì)的分析了Python中動(dòng)態(tài)參數(shù)的功能及使用技巧,需要的朋友可以參考下2015-05-05
為項(xiàng)目選擇的Python解釋器無(wú)效兩種解決方式
在編程和軟件開(kāi)發(fā)過(guò)程中,尤其是使用Python這類解釋型語(yǔ)言時(shí),選擇合適的解釋器(Interpreter)至關(guān)重要,這篇文章主要介紹了為項(xiàng)目選擇的Python解釋器無(wú)效的兩種解決方式,需要的朋友可以參考下2025-09-09
Python去除字符串中的標(biāo)點(diǎn)符號(hào)的最優(yōu)方式
在Python編程中,去除字符串標(biāo)點(diǎn)符號(hào)是一項(xiàng)常見(jiàn)任務(wù),關(guān)鍵在于文本分析和數(shù)據(jù)清洗,Python提供了多種方法,包括使用str.replace()、str.translate()結(jié)合str.maketrans(),以及使用正則表達(dá)式,另外,可以利用string模塊中的punctuation屬性快速實(shí)現(xiàn)2024-09-09
Python摳圖教程之使用OpenCV實(shí)現(xiàn)背景去除
這篇文章主要給大家介紹了關(guān)于Python摳圖教程之使用OpenCV實(shí)現(xiàn)背景去除的相關(guān)資料,背景去除是在很多視覺(jué)應(yīng)用里的主要預(yù)處理步驟,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-10-10
Python巧用SnowNLP實(shí)現(xiàn)生成srt字幕文件
SnowNLP是一個(gè)可以方便的處理中文文本內(nèi)容的python類庫(kù),本文主要為大家詳細(xì)介紹了Python如何巧用SnowNLP實(shí)現(xiàn)將一段話一鍵生成srt字幕文件,感興趣的可以了解下2024-01-01

