首页 > 应用开发 > Python > Python写的内存泄漏检测工具
Python 内存泄漏检测工具
# memory_leak_detector.py
import tracemalloc
import gc
import time
import psutil
import os
from collections import defaultdict
class MemoryLeakDetector:
def __init__(self, interval=5, top=10):
self.interval = interval
self.top = top
self.process = psutil.Process(os.getpid())
def get_memory_mb(self):
return self.process.memory_info().rss / 1024 / 1024
def print_top_stats(self, snapshot1, snapshot2):
print("\n================ 内存增长分析 ================\n")
top_stats = snapshot2.compare_to(snapshot1, 'lineno')
for index, stat in enumerate(top_stats[:self.top], 1):
print(f"[{index}] {stat}")
print("\n=============================================\n")
def object_growth(self):
gc.collect()
objs = gc.get_objects()
counter = defaultdict(int)
for obj in objs:
counter[type(obj).__name__] += 1
sorted_objs = sorted(counter.items(), key=lambda x: x[1], reverse=True)
print("\n========== 当前对象数量 TOP 20 ==========\n")
for name, count in sorted_objs[:20]:
print(f"{name:<30} {count}")
print("\n=========================================\n")
def run(self):
print("启动内存泄漏检测...")
print(f"PID: {os.getpid()}")
tracemalloc.start(25)
snapshot1 = tracemalloc.take_snapshot()
while True:
mem_before = self.get_memory_mb()
print(f"\n当前内存: {mem_before:.2f} MB")
time.sleep(self.interval)
gc.collect()
snapshot2 = tracemalloc.take_snapshot()
mem_after = self.get_memory_mb()
print(f"检测后内存: {mem_after:.2f} MB")
diff = mem_after - mem_before
print(f"内存变化: {diff:.2f} MB")
if diff > 1:
print("\n发现疑似内存增长!")
self.print_top_stats(snapshot1, snapshot2)
self.object_growth()
snapshot1 = snapshot2
if __name__ == "__main__":
detector = MemoryLeakDetector(
interval=5,
top=15
)
detector.run()
安装依赖
pip install psutil
运行
python memory_leak_detector.py
输出示例
当前内存: 152.11 MB
检测后内存: 166.42 MB
内存变化: 14.31 MB
发现疑似内存增长!
[1] app.py:88: size=12.5 MiB (+12.5 MiB), count=50000 (+50000)
[2] crawler.py:120: size=5.1 MiB (+5.1 MiB), count=20000 (+20000)
========== 当前对象数量 TOP 20 ==========
dict 102345
list 83211
str 72344
WebElement 50000
能检测什么
1. list 无限增长
例如:
cache = []
while True:
cache.append("A" * 100000)
会直接定位:
main.py:12
2. Selenium WebElement 泄漏
很多人写:
elements.append(driver.find_element(...))
导致 WebElement 不释放。
工具会显示:
WebElement 50000
3. requests 响应没关闭
例如:
requests.get(url)
没有:
response.close()
也能看到增长。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70050070/viewspace-3117346/ ,如需转载,请注明出处,否则将追究法律责任。