本文目录导读:

- 使用弱引用打破循环引用
- 显式删除大对象
- 使用生成器替代列表
- 手动管理垃圾回收
- 使用
__slots__减少内存开销 - 使用内存分析工具监控
- 使用
array或numpy替代列表 - 使用
mmap处理大文件 - 完整的内存管理示例
- 监控和日志
防止Python进程内存持续增长,通常需要从对象生命周期管理、数据结构选择、资源释放以及内存分析工具几个方面入手,以下是系统性的解决方案:
使用弱引用打破循环引用
import weakref
import gc
class Node:
def __init__(self, value):
self.value = value
self.parent = None # 使用弱引用
self.children = []
def set_parent(self, parent_node):
# 使用弱引用避免循环引用
self.parent = weakref.ref(parent_node)
# 手动触发垃圾回收
gc.collect()
显式删除大对象
def process_large_data():
# 处理完立即释放
large_list = [i for i in range(10**7)]
result = sum(large_list)
# 显式删除
del large_list
return result
# 或者使用 with 语句管理上下文
class LargeDataProcessor:
def __enter__(self):
self.data = self.load_large_data()
return self
def __exit__(self, *args):
# 退出时自动清理
del self.data
gc.collect()
使用生成器替代列表
# 错误示例:一次性加载所有数据
def load_all_data():
return [expensive_operation(i) for i in range(10**6)]
# 正确示例:使用生成器
def stream_data():
for i in range(10**6):
yield expensive_operation(i)
# 使用
for item in stream_data():
process(item)
手动管理垃圾回收
import gc
class MemoryManager:
def __init__(self):
# 关闭自动垃圾回收
gc.disable()
# 设置阈值
gc.set_threshold(700, 10, 5)
def process_batch(self, batch_size=1000):
for i in range(batch_size):
# 处理数据
result = expensive_operation(i)
# 每处理100个对象,手动触发一次回收
if i % 100 == 0:
gc.collect(generation=0) # 只回收第0代
# 批次结束后完全回收
gc.collect()
使用 __slots__ 减少内存开销
# 普通类(每个实例有 __dict__)
class RegularPoint:
def __init__(self, x, y):
self.x = x
self.y = y
# 使用 __slots__(没有 __dict__,内存更小)
class SlottedPoint:
__slots__ = ['x', 'y']
def __init__(self, x, y):
self.x = x
self.y = y
# 内存对比
import sys
regular = RegularPoint(1, 2)
slotted = SlottedPoint(1, 2)
print(f"Regular: {sys.getsizeof(regular)} bytes") # 56
print(f"Slotted: {sys.getsizeof(slotted)} bytes") # 40
使用内存分析工具监控
import tracemalloc
import objgraph
class MemoryMonitor:
def __init__(self):
tracemalloc.start()
def get_memory_snapshot(self):
snapshot = tracemalloc.take_snapshot()
top_stats = snapshot.statistics('lineno')
print("[ Top 10 memory consumers ]")
for stat in top_stats[:10]:
print(stat)
def find_leaks(self):
# 找出对象增长
growth = objgraph.growth(limit=10)
print("Object growth analysis:")
for obj_type, count, delta in growth:
print(f"{obj_type}: {count} (+{delta})")
# 使用
monitor = MemoryMonitor()
# 运行你的代码
monitor.get_memory_snapshot()
使用 array 或 numpy 替代列表
import array
import numpy as np
# 使用 array 模块
def process_with_array(size=10**6):
arr = array.array('d', [0.0]) * size # 双精度浮点数数组
for i in range(size):
arr[i] = i * 1.5
return arr
# 使用 numpy(更高效)
def process_with_numpy(size=10**6):
arr = np.zeros(size, dtype=np.float64)
arr[:] = np.arange(size) * 1.5
return arr
使用 mmap 处理大文件
import mmap
import os
def process_large_file(filename):
with open(filename, 'r') as f:
with mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) as mm:
# 直接处理内存映射,不加载到Python内存
for line in iter(mm.readline, b''):
process(line)
# mmap 自动释放
完整的内存管理示例
import gc
import weakref
from functools import lru_cache
class MemorySafeProcessor:
def __init__(self, max_cache_size=100):
gc.enable()
self._cache = {}
self._max_cache_size = max_cache_size
self._memory_usage = 0
@lru_cache(maxsize=50)
def cached_operation(self, key):
"""带缓存的耗时操作"""
return expensive_computation(key)
def process_batch(self, items):
results = []
for i, item in enumerate(items):
result = self.cached_operation(item)
results.append(result)
# 定期清理
if i % 100 == 0:
self._cleanup()
return results
def _cleanup(self):
# 清除过大的缓存
if len(self._cache) > self._max_cache_size:
self._cache.clear()
# 检查内存使用
import psutil
process = psutil.Process()
memory_percent = process.memory_percent()
if memory_percent > 80: # 如果内存使用超过80%
gc.collect()
self._cache.clear()
print(f"Memory cleanup triggered: {memory_percent}%")
def __del__(self):
# 清理资源
self._cache.clear()
gc.collect()
# 使用示例
processor = MemorySafeProcessor()
results = processor.process_batch(range(10000))
监控和日志
import psutil
import logging
from memory_profiler import profile
logging.basicConfig(level=logging.INFO)
@profile # 装饰器监控函数内存
def monitored_function():
import numpy as np
# 模拟内存增长
data = []
for i in range(1000):
data.append(np.random.rand(1000, 1000))
# 内存监控
process = psutil.Process()
memory_mb = process.memory_info().rss / 1024 / 1024
if memory_mb > 500: # 超过500MB报警
logging.warning(f"Memory usage: {memory_mb:.2f} MB")
# 清理
del data[:]
break
return "Done"
# 运行监控
monitored_function()
| 策略 | 适用场景 | 效果 |
|---|---|---|
| 弱引用 | 循环引用问题 | 防止内存泄漏 |
| 生成器 | 大数据流处理 | 即时内存使用 |
__slots__ |
大量小对象 | 减少30-50%内存 |
| array/numpy | 数值计算 | 高效存储 |
| mmap | 大文件处理 | 几乎不占内存 |
| gc.collect() | 手动控制 | 及时回收 |
| 分析工具 | 定位问题 | 预防性维护 |
最佳实践:
- 优先使用生成器而不是列表
- 大对象用完立即
del - 启用垃圾回收但不要频繁调用
- 使用
memory_profiler和objgraph定期检查 - 对于长时间运行的服务,设置内存上限并重启
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播