Python如何监控并获取内存使用情况

 更新时间:2026年03月29日 09:23:29   作者:detayun  
在Python开发中,监控内存使用情况对于性能优化和问题排查至关重要,本文将介绍多种获取内存使用情况的方法,大家可以根据自己的需要进行选择

在Python开发中,监控内存使用情况对于性能优化、资源管理和问题排查至关重要。本文将介绍多种获取内存使用情况的方法,涵盖操作系统级监控、Python对象内存分析以及第三方工具的使用。

一、为什么需要监控内存使用

  • 性能优化:识别内存泄漏或过度内存消耗
  • 资源管理:在容器化环境中控制资源使用
  • 问题排查:分析内存异常增长的原因
  • 容量规划:为系统扩展提供数据支持

二、操作系统级内存监控

方法1:使用psutil库(跨平台推荐)

psutil是一个跨平台库,可以轻松获取系统内存信息:

import psutil

def get_system_memory_info():
    """获取系统内存使用情况"""
    mem = psutil.virtual_memory()
    swap = psutil.swap_memory()
    
    print("=== 系统内存信息 ===")
    print(f"总内存: {mem.total / (1024**3):.2f} GB")
    print(f"可用内存: {mem.available / (1024**3):.2f} GB")
    print(f"已用内存: {mem.used / (1024**3):.2f} GB")
    print(f"内存使用率: {mem.percent}%")
    print("\n=== 交换分区信息 ===")
    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系统中,可以直接读取/proc/meminfo文件:

def get_linux_memory_info():
    """Linux系统内存信息(通过/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])  # 取第一个数值
                    mem_info[key] = value
            
        # 转换为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内存信息 ===")
        print(f"总内存: {total:.2f} GB")
        print(f"可用内存: {available:.2f} GB")
        print(f"已用内存: {used:.2f} GB")
        print(f"内存使用率: {(used/total)*100:.1f}%")
    except FileNotFoundError:
        print("无法读取/proc/meminfo(非Linux系统)")

# 使用示例
get_linux_memory_info()

方法3:使用resource模块(Unix系统)

Python内置的resource模块可以获取当前进程的内存使用:

import resource

def get_process_memory_unix():
    """获取当前进程的内存使用(Unix系统)"""
    try:
        # 获取最大驻留集大小(RSS)
        rss = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
        
        # 单位转换(不同系统单位不同)
        if hasattr(resource, 'getpagesize'):
            page_size = resource.getpagesize()
            rss_gb = rss * page_size / (1024**3)
        else:
            # 假设单位是KB(常见于Linux)
            rss_gb = rss / (1024**2)
            
        print(f"当前进程内存使用: {rss_gb:.2f} GB")
    except AttributeError:
        print("resource模块功能在当前系统不可用")

# 使用示例
get_process_memory_unix()

三、Python对象内存分析

方法1:使用sys.getsizeof()

获取单个Python对象的大小(注意:不包含对象引用的其他对象):

import sys

def object_memory_example():
    """演示sys.getsizeof()的使用"""
    print("基本类型内存占用:")
    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库(深度分析)

pympler提供了更全面的内存分析工具:

from pympler import asizeof, summary, muppy

def deep_memory_analysis():
    """深度内存分析示例"""
    # 创建一些测试对象
    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
    }
    
    # 获取单个对象大小
    print(f"列表大小: {asizeof.asizeof(test_data['list'])/1024:.2f} KB")
    
    # 获取所有对象的汇总信息
    all_objects = muppy.get_objects()
    sum_obj = summary.summarize(all_objects)
    summary.print_(sum_obj)
    
    # 获取特定类型对象的汇总
    from pympler.class_tracker import ClassTracker
    tracker = ClassTracker()
    tracker.track_object(test_data)
    tracker.create_snapshot()
    tracker.stats.print_()

# 使用示例(注释掉以避免输出过长)
# deep_memory_analysis()

方法3:跟踪内存变化

import tracemalloc

def track_memory_usage():
    """跟踪内存分配变化"""
    tracemalloc.start()
    
    # 第一次快照
    snapshot1 = tracemalloc.take_snapshot()
    
    # 执行一些内存分配操作
    data = [i for i in range(100000)]
    
    # 第二次快照
    snapshot2 = tracemalloc.take_snapshot()
    
    # 比较两个快照
    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()

四、实时监控内存使用

方法1:使用memory_profiler

# 需要先安装: pip install memory_profiler
from memory_profiler import memory_usage
import time

def my_function():
    """测试函数内存使用"""
    data = [i for i in range(100000)]
    time.sleep(1)
    return sum(data)

# 监控函数内存使用
mem_usage = memory_usage((my_function, (), {}), interval=0.1)
print(f"最大内存使用: {max(mem_usage):.2f} MB")

方法2:装饰器方式监控

from memory_profiler import profile

@profile
def memory_intensive_function():
    """使用装饰器监控内存"""
    a = [1] * (10 ** 6)
    b = [2] * (2 * 10 ** 7)
    del b
    return a

# 使用示例(运行时会输出内存使用报告)
# memory_intensive_function()

五、不同场景下的最佳实践

1. Web应用内存监控

# 在Flask应用中监控内存
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",   # 虚拟内存大小
        'percent': f"{process.memory_percent():.1f}%"
    }

2. 数据处理任务监控

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"数据处理最大内存使用: {max(mem_usage):.2f} MB")

process_large_data()

3. 长期运行服务的监控

import time
import psutil

def monitor_memory_loop(interval=60):
    """定期监控内存使用"""
    while True:
        mem = psutil.virtual_memory()
        print(f"[{time.ctime()}] 内存使用: {mem.percent}%")
        time.sleep(interval)

# 在生产环境中建议使用日志记录而非print
# monitor_memory_loop()

六、注意事项

单位转换:注意不同API返回的单位可能是字节、KB或MB

共享内存:某些工具计算的内存可能包含共享库占用的内存

GC影响:Python的垃圾回收机制会影响内存测量结果

容器环境:在Docker等容器中,需要使用cgroup感知的工具

多线程:多线程环境下内存测量可能不准确

七、总结

方法适用场景特点
psutil系统级监控跨平台,信息全面
/proc/meminfoLinux系统直接读取内核信息
sys.getsizeof()对象大小简单快速,但不递归
pympler深度分析提供对象关系和变化跟踪
memory_profiler函数级监控装饰器方式,适合开发调试
tracemalloc内存变化跟踪Python内置,无需安装

根据具体需求选择合适的方法:

  • 系统级监控推荐psutil
  • 开发调试推荐memory_profilerpympler
  • 生产环境监控建议结合系统工具和自定义日志

通过合理使用这些工具,可以有效地监控和管理Python应用的内存使用情况。

到此这篇关于Python如何监控并获取内存使用情况的文章就介绍到这了,更多相关Python获取内存使用情况内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python多任务版静态Web服务器实现示例

    Python多任务版静态Web服务器实现示例

    这篇文章主要为大家介绍了Python静态Web服务器多任务版实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • Python tkinter 下拉日历控件代码

    Python tkinter 下拉日历控件代码

    这篇文章主要介绍了Python tkinter 下拉日历控件代码,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-03-03
  • OpenCV图像变换之傅里叶变换的一些应用

    OpenCV图像变换之傅里叶变换的一些应用

    这篇文章主要给大家介绍了关于OpenCV图像变换之傅里叶变换的相关资料,傅里叶变换可以将一幅图片分解为正弦和余弦两个分量,换而言之,他可以将一幅图像从其空间域(spatial domain)转换为频域(frequency domain),需要的朋友可以参考下
    2021-07-07
  • 解决使用python print打印函数返回值多一个None的问题

    解决使用python print打印函数返回值多一个None的问题

    这篇文章主要介绍了解决使用python print打印函数返回值多一个None的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-04-04
  • Python循环取数组的值的方法实现

    Python循环取数组的值的方法实现

    本文主要介绍了两种Python中遍历数组的方法,for循环和索引,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-12-12
  • python爬虫 基于requests模块发起ajax的get请求实现解析

    python爬虫 基于requests模块发起ajax的get请求实现解析

    这篇文章主要介绍了python爬虫 基于requests模块发起ajax的get请求实现解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-08-08
  • pyqt5中QThread在使用时出现重复emit的实例

    pyqt5中QThread在使用时出现重复emit的实例

    今天小编就为大家分享一篇pyqt5中QThread在使用时出现重复emit的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-06-06
  • tensorflow-gpu2.3版本安装步骤

    tensorflow-gpu2.3版本安装步骤

    这篇文章主要介绍了tensorflow-gpu2.3版本安装步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • Pycharm中新添加或者导入项目文件名红色的解决方法

    Pycharm中新添加或者导入项目文件名红色的解决方法

    Pycharm的代码中添加新的文件夹,发现文件夹下的文件名是红色的,遇到这样的问题如何解决呢,下面小编给大家带来了Pycharm中新添加或者导入项目文件名红色的解决方法,感兴趣的朋友一起看看吧
    2023-12-12
  • 将Python字符串拼接成字节的多种方式

    将Python字符串拼接成字节的多种方式

    在 Python 中,将字符串拼接成字节有多种方式,主要取决于字符串的编码和具体需求,这些方法涵盖了从基本字符串拼接到底层字节处理的多种场景,本文通过代码给大家介绍的非常详细,需要的朋友可以参考下
    2026-03-03

最新评论