Python内存监控案例如何监控内存占用

wen python案例 23

本文目录导读:

Python内存监控案例如何监控内存占用

  1. 基础内存监控器
  2. 持续内存监控器
  3. 函数级内存监控装饰器
  4. 完整的内存监控系统
  5. 使用memory_profiler(第三方库)
  6. 安装依赖
  7. 使用建议

我来分享几个Python内存监控的实用案例:

基础内存监控器

import psutil
import os
import time
from datetime import datetime
class MemoryMonitor:
    def __init__(self):
        self.process = psutil.Process(os.getpid())
    def get_memory_usage(self):
        """获取当前进程内存使用"""
        memory_info = self.process.memory_info()
        return {
            'rss': memory_info.rss / 1024 / 1024,  # MB
            'vms': memory_info.vms / 1024 / 1024,  # MB
            'percent': self.process.memory_percent(),
            'time': datetime.now().strftime('%H:%M:%S')
        }
    def monitor_task(self, task_func, *args, **kwargs):
        """监控任务执行期间的内存变化"""
        start_mem = self.get_memory_usage()
        print(f"开始内存: RSS={start_mem['rss']:.2f}MB, VMS={start_mem['vms']:.2f}MB")
        result = task_func(*args, **kwargs)
        end_mem = self.get_memory_usage()
        print(f"结束内存: RSS={end_mem['rss']:.2f}MB, VMS={end_mem['vms']:.2f}MB")
        print(f"内存变化: +{end_mem['rss']-start_mem['rss']:.2f}MB")
        return result
# 使用示例
monitor = MemoryMonitor()
def memory_intensive_task(size_mb):
    """模拟内存密集型任务"""
    data = [0] * (size_mb * 1024 * 1024 // 8)  # 每个int大约28字节
    time.sleep(2)
    return len(data)
# 监控任务
result = monitor.monitor_task(memory_intensive_task, 100)

持续内存监控器

import threading
import matplotlib.pyplot as plt
from collections import deque
class ContinuousMonitor:
    def __init__(self, interval=1):
        self.interval = interval
        self.monitor = MemoryMonitor()
        self.memory_history = deque(maxlen=100)
        self.time_history = deque(maxlen=100)
        self.is_running = False
    def start(self):
        """启动持续监控"""
        self.is_running = True
        self.thread = threading.Thread(target=self._monitor_loop)
        self.thread.daemon = True
        self.thread.start()
    def stop(self):
        """停止监控"""
        self.is_running = False
    def _monitor_loop(self):
        """监控循环"""
        while self.is_running:
            mem_info = self.monitor.get_memory_usage()
            self.memory_history.append(mem_info['rss'])
            self.time_history.append(mem_info['time'])
            # 实时打印
            self._print_status(mem_info)
            time.sleep(self.interval)
    def _print_status(self, mem_info):
        """打印状态"""
        mem_bar = '█' * int(mem_info['percent'] / 2) + '░' * (50 - int(mem_info['percent'] / 2))
        print(f"\r[{mem_info['time']}] 内存: {mem_info['rss']:.1f}MB | {mem_bar} {mem_info['percent']:.1f}%", end='')
    def plot_memory_usage(self):
        """绘制内存使用曲线"""
        plt.figure(figsize=(10, 6))
        plt.plot(list(self.time_history), list(self.memory_history), 'b-', linewidth=2)
        plt.xlabel('时间')
        plt.ylabel('内存使用 (MB)')
        plt.title('内存使用监控')
        plt.xticks(rotation=45)
        plt.grid(True, alpha=0.3)
        plt.tight_layout()
        plt.show()
# 使用示例
monitor = ContinuousMonitor(interval=0.5)
monitor.start()
time.sleep(10)  # 模拟程序运行
monitor.stop()
monitor.plot_memory_usage()

函数级内存监控装饰器

import functools
import tracemalloc
def memory_profile(func):
    """内存监控装饰器"""
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        # 启动内存追踪
        tracemalloc.start()
        # 记录初始内存
        snapshot1 = tracemalloc.take_snapshot()
        # 执行函数
        result = func(*args, **kwargs)
        # 记录结束内存
        snapshot2 = tracemalloc.take_snapshot()
        # 计算差异
        top_stats = snapshot2.compare_to(snapshot1, 'lineno')
        print(f"\n函数 '{func.__name__}' 内存分析:")
        print(f"{'='*60}")
        total_diff = sum(stat.size_diff for stat in top_stats)
        print(f"总内存变化: {total_diff / 1024:.2f} KB")
        # 显示内存变化最大的10个位置
        print(f"\n{'内存变化最大的位置':^50}")
        print(f"{'大小(KB)':<12} {'计数':<10} {'位置':<30}")
        print("-"*52)
        for stat in top_stats[:10]:
            size_kb = stat.size_diff / 1024
            if size_kb != 0:
                print(f"{size_kb:<12.1f} {stat.count_diff:<10} {str(stat.traceback)[:30]}")
        tracemalloc.stop()
        return result
    return wrapper
# 使用示例
@memory_profile
def create_large_list(size):
    """创建大列表"""
    return [i for i in range(size)]
@memory_profile
def process_data(size):
    """处理数据"""
    data = [x * 2 for x in range(size)]
    data_dict = {i: x for i, x in enumerate(data)}
    return data_dict
create_large_list(1000000)
process_data(500000)

完整的内存监控系统

import json
import logging
from dataclasses import dataclass
from typing import Callable, Any
@dataclass
class MemoryAlert:
    """内存警报"""
    threshold: float
    current: float
    message: str
    timestamp: datetime
class MemoryMonitoringSystem:
    def __init__(self, 
                 warning_threshold: float = 80.0,  # 警告阈值 (%)
                 critical_threshold: float = 90.0,  # 严重阈值 (%)
                 log_file: str = 'memory_monitor.log'):
        self.warning_threshold = warning_threshold
        self.critical_threshold = critical_threshold
        self.alerts = []
        # 配置日志
        logging.basicConfig(
            filename=log_file,
            level=logging.INFO,
            format='%(asctime)s - %(levelname)s - %(message)s'
        )
        self.logger = logging.getLogger(__name__)
        self.monitor = MemoryMonitor()
    def check_memory(self) -> dict:
        """检查内存状态"""
        mem_info = self.monitor.get_memory_usage()
        # 检查是否需要发出警报
        if mem_info['percent'] >= self.critical_threshold:
            alert = MemoryAlert(
                threshold=self.critical_threshold,
                current=mem_info['percent'],
                message=f"严重内存使用率: {mem_info['percent']:.1f}%",
                timestamp=datetime.now()
            )
            self.alerts.append(alert)
            self.logger.critical(alert.message)
        elif mem_info['percent'] >= self.warning_threshold:
            alert = MemoryAlert(
                threshold=self.warning_threshold,
                current=mem_info['percent'],
                message=f"内存使用率警告: {mem_info['percent']:.1f}%",
                timestamp=datetime.now()
            )
            self.alerts.append(alert)
            self.logger.warning(alert.message)
        return mem_info
    def save_snapshot(self, filename: str = 'memory_snapshot.json'):
        """保存内存快照"""
        mem_info = self.check_memory()
        snapshot = {
            'timestamp': datetime.now().isoformat(),
            'memory': mem_info,
            'alerts': [
                {
                    'threshold': a.threshold,
                    'current': a.current,
                    'message': a.message,
                    'time': a.timestamp.isoformat()
                }
                for a in self.alerts[-10:]  # 只保存最近10条警报
            ]
        }
        with open(filename, 'w') as f:
            json.dump(snapshot, f, indent=2)
        self.logger.info(f"内存快照已保存: {filename}")
    def run_monitoring(self, 
                       duration: int = 60, 
                       callback: Callable = None):
        """运行监控"""
        start_time = time.time()
        snapshot_count = 0
        while time.time() - start_time < duration:
            mem_info = self.check_memory()
            if callback:
                callback(mem_info)
            # 每10秒保存一次快照
            if snapshot_count % 10 == 0:
                self.save_snapshot(f'memory_snapshot_{snapshot_count}.json')
            snapshot_count += 1
            time.sleep(1)
        # 生成报告
        self.generate_report()
    def generate_report(self):
        """生成监控报告"""
        print(f"\n{'='*50}")
        print(f"内存监控报告")
        print(f"{'='*50}")
        print(f"监控时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
        print(f"警报总数: {len(self.alerts)}")
        warning_alerts = [a for a in self.alerts if a.current < self.critical_threshold]
        critical_alerts = [a for a in self.alerts if a.current >= self.critical_threshold]
        print(f"警告警报: {len(warning_alerts)}")
        print(f"严重警报: {len(critical_alerts)}")
        if self.alerts:
            print(f"\n最近警报:")
            for alert in self.alerts[-3:]:
                print(f"  - [{alert.timestamp}] {alert.message}")
# 使用示例
def memory_callback(mem_info):
    """内存监控回调函数"""
    if mem_info['percent'] > 75:
        print(f"⚠  注意: 内存使用较高 ({mem_info['percent']:.1f}%)")
def main():
    # 创建监控系统
    ms = MemoryMonitoringSystem(
        warning_threshold=70.0,
        critical_threshold=85.0
    )
    # 模拟内存使用
    def memory_workload():
        data = []
        for i in range(10):
            print(f"\n创建大对象 #{i+1}")
            data.append([j for j in range(1000000)])
            time.sleep(2)
        # 清理一部分
        print("\n清理部分内存...")
        data = data[:3]
        time.sleep(2)
        return data
    # 运行监控(运行30秒)
    print("开始内存监控...")
    # 在单独的线程中运行监控
    monitor_thread = threading.Thread(
        target=ms.run_monitoring,
        args=(30, memory_callback)
    )
    monitor_thread.start()
    # 执行内存密集型任务
    memory_workload()
    monitor_thread.join()
    print("\n监控完成!")
if __name__ == '__main__':
    main()

使用memory_profiler(第三方库)

# 安装: pip install memory_profiler
from memory_profiler import profile
import time
@profile
def memory_hungry_function():
    """使用memory_profiler装饰器进行内存分析"""
    # 创建大列表
    large_list = [i for i in range(1000000)]
    print(f"大列表大小: {len(large_list)}")
    # 创建字典
    large_dict = {i: str(i) for i in range(500000)}
    print(f"大字典大小: {len(large_dict)}")
    # 字符串操作
    large_string = " ".join([str(i) for i in range(100000)])
    # 清理
    del large_list
    del large_dict
    time.sleep(1)
    return "完成"
# 运行函数
result = memory_hungry_function()

安装依赖

# 基础依赖
pip install psutil matplotlib
# 可选:更高级的内存分析
pip install memory_profiler objgraph

使用建议

  1. 生产环境监控:使用MemoryMonitoringSystem结合日志系统
  2. 开发调试:使用@memory_profile装饰器分析函数内存
  3. 实时监控:使用ContinuousMonitor可视化内存变化
  4. 性能优化:使用memory_profiler@profile装饰器

这些案例涵盖了从简单到复杂的各种内存监控需求,可以根据实际场景选择合适的方案。

抱歉,评论功能暂时关闭!