有没有大神能解释一下为什么 Python 循环中无法释放内存

2021-12-24 17:05:25 +08:00
 liuxingdeyu
工作中遇到一个问题,启动多个 worker 去跑任务,任务是把用 bfmatch 去匹配特征点,由于图量比较大,导致一直爆内存,现在用了一个监控内存后重启进程的临时办法,然后自己写了个例子:
while True:
x = []
for i in range(10000000000):
x.append(i)
这样内存也会很快堆起来
然后做了这样的改动:
while True:
x = []
for i in range(10000000000):
x.append(i)
del x
gc.collect()
这样内存依旧会很快堆起来
希望有大佬能解释一下原因,顺便谁能推荐个 python 查看堆栈的工具,万分感谢
3020 次点击
所在节点    Python
9 条回复
ch2
2021-12-24 17:15:28 +08:00
先 del 再 gc.collect()内存就会回收的,内鬼可能是别的对象
keepeye
2021-12-24 17:20:08 +08:00
del x 之后用 gc.is_finalized(x)看下是不是 True
ipwx
2021-12-24 17:22:21 +08:00
不懂,你在循环里 del x 岂不是没用了,这循环到底干嘛的。。
ipwx
2021-12-24 17:25:32 +08:00
In [4]: for i in range(10000000000):
...: if i % 10000 == 0:
...: del x
...: gc.collect()
...: x = []
...: else:
...: x.append(i)


这个我验证不会爆内存
liuxingdeyu
2021-12-24 20:00:41 +08:00
@ch2 确实是没删干净的问题,所以导致了爆内存的问题,还有就是我在做测试的时候,由于 0 过多,导致本地的内存不够用了,再加上由于某些未知的原因,没能触发 gc
@keepeye 在 del 之后,会报错的,因为 del 后会认为这个变量没有定义
@ipwx 这只是个例子,用来验证原因的,你这个爆报内存是因为你加了个 1 万取余数的操作大大限制了数量而且没有 while True
ixuuux
2021-12-24 23:14:12 +08:00
尝试把 del x 改为 x.clear()
jones2000
2021-12-25 12:47:23 +08:00
把循环放到函数里面这样, 函数结束应该就会自动释放函数内使用的局部变量。

def fun():
x = []
for i in range(10000000000):
x.append(i)


while True:
fun()
ipwx
2021-12-25 21:08:15 +08:00
@liuxingdeyu 好吧,那我更正我的说法。我的程序始终稳定在 0.3MB 内存不会增长。所以是删干净了
liuxingdeyu
2022-01-07 18:36:52 +08:00
@ch2 @keepeye @ixuuux 感谢各位,最终我在我的代码中找到了问题的所在,一开始的思路跑偏了,最终发现的结果是问题出在了 multiprocessing 上,开了一堆进程,把一个大号的列表扔进去当参数,最后发现在读取处理的时候,内存会慢慢的变高,特别是把里面的内容取出来,然后从 list 转到 np.array 的时候

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/824267

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX