在什么情况下看起来像 python 内存泄漏的问题可能不是泄漏?
Under what circumstances could an issue that looks like a python memory leak not be a leak?
我们有一个使用 PyXB 和其他库处理大量 XML 和 JSON 数据的 python 脚本,并且此脚本消耗的 RAM 量不断增加,直到机器内存不足。
除了内存泄漏,还有其他情况会导致这种高内存使用率吗?
在我们的例子中,看起来像泄漏的原因是我们的 python 代码消耗 RAM 的速度比 python 垃圾收集器愿意清理垃圾的速度快。
我们案例中的解决方案是在脚本中的每个工作单元结束时强制进行手动垃圾回收,如下所示:
gc.collect()
这使内存得到控制。
tracemalloc 库证实了似乎正在泄漏的特定代码并未泄漏。收集了垃圾,拍了快照,然后对比前后的快照,证明没有分配额外的内存。
for _ in range(10000):
gc.collect();
snapshot1 = tracemalloc.take_snapshot()
response = test_parsing("assets.xml")
del response
gc.collect();
snapshot2 = tracemalloc.take_snapshot()
top_stats = snapshot2.compare_to(snapshot1, 'lineno')
print("[ Non Zero differences ]")
for stat in top_stats:
if (stat.size_diff != 0):
print(stat)
在我们的例子中,上面的非零差异列表在每次迭代后都是空的,证明没有泄漏。
我们有一个使用 PyXB 和其他库处理大量 XML 和 JSON 数据的 python 脚本,并且此脚本消耗的 RAM 量不断增加,直到机器内存不足。
除了内存泄漏,还有其他情况会导致这种高内存使用率吗?
在我们的例子中,看起来像泄漏的原因是我们的 python 代码消耗 RAM 的速度比 python 垃圾收集器愿意清理垃圾的速度快。
我们案例中的解决方案是在脚本中的每个工作单元结束时强制进行手动垃圾回收,如下所示:
gc.collect()
这使内存得到控制。
tracemalloc 库证实了似乎正在泄漏的特定代码并未泄漏。收集了垃圾,拍了快照,然后对比前后的快照,证明没有分配额外的内存。
for _ in range(10000):
gc.collect();
snapshot1 = tracemalloc.take_snapshot()
response = test_parsing("assets.xml")
del response
gc.collect();
snapshot2 = tracemalloc.take_snapshot()
top_stats = snapshot2.compare_to(snapshot1, 'lineno')
print("[ Non Zero differences ]")
for stat in top_stats:
if (stat.size_diff != 0):
print(stat)
在我们的例子中,上面的非零差异列表在每次迭代后都是空的,证明没有泄漏。