Python程序在运行时,会根据需要在内存中动态地分配内存空间来存储程序中的变量、对象、数据结构等。这些内存空间是临时的,并且随着程序的执行而动态地创建和销毁。一旦计算完成,如果需要将结果持久化,程序可能会将结果写入到硬盘等永久性存储器中,如文件、数据库等。
然而,当处理的数据量非常大时,如果内存管理不当,或者程序没有有效地利用内存资源,就可能导致内存消耗过快,最终耗尽可用内存。这种情况通常被称为"Out of Memory"(OOM)错误,或者俗称"爆内存"。一旦发生OOM错误,操作系统可能会终止Python程序,因为它无法再为程序提供更多的内存空间。
虽然python 有垃圾回收机制,但是也不是万能的。万一有哪个地方造成了内存泄漏,要怎么调优?这里介绍几个python常用调优的库。
1. objgraph
objgraph
是一个用于显示 Python 对象引用图的第三方库,它可以发现循环引用等问题。
安装
pip install objgraph
示例
import objgraph
# 初始化两个列表并创建循环引用
a = [i for i in range(10000000)]
b = [i for i in range(10000000)]
a.append(b)
b.append(a)
# 使用 objgraph 查找循环引用
objgraph.show_cycles([a,b], filename='cycles.png') # 这会生成一个 PNG 图片显示循环引用
2. tracemalloc
tracemalloc
是 Python 的一个标准库模块,用于跟踪内存块的分配。
示例
import tracemalloc
# 开始跟踪
tracemalloc.start()
# 分配一些内存
numbers = [i for i in range(1000000)]
# 获取当前内存块的快照
snapshot = tracemalloc.take_snapshot()
# 打印前 10 个内存分配最大的统计信息
top_stats = snapshot.statistics('lineno')
print("[ Top 10 ]")
for stat in top_stats[:10]:
print(stat)
# 停止跟踪(尽管 tracemalloc 通常不需要显式停止)
# tracemalloc.stop()
3. memory_profiler
memory_profiler
是一个命令行工具,用于分析 Python 脚本或函数的内存使用情况。
安装
pip install memory-profiler
示例
# 使用 mprof run 运行你的脚本
mprof run your_script.py
# 使用 mprof plot 绘制内存使用图
mprof plot
在Python 脚本中,也可以使用 @profile
装饰器来分析特定函数的内存使用:
from memory_profiler import profile
@profile
def my_function():
# 你的代码
pass
my_function()
然后可以直接运行脚本,memory_profiler
会在运行时分析并打印出 my_function
的内存使用情况。
4. psutil
psutil
是一个跨平台库,用于获取系统利用率(CPU, 内存, 磁盘, 网络, 进程等)信息。
安装
pip install psutil
示例
import psutil
import os
def print_memory_usage():
pid = os.getpid()
process = psutil.Process(pid)
meminfo = process.memory_info()
print(f"Memory usage: {meminfo.rss / (1024 ** 3):.2f} GB")
# 在你的代码的不同部分调用 print_memory_usage()
print_memory_usage()
# ... 你的代码 ...
print_memory_usage()
使用 psutil
,可以监控你的 Python 进程在不同代码段中的内存使用情况,从而识别内存泄漏或优化内存使用。
以上只是做一个简单的介绍,如果有需要,可以查看官方文档。