为什么我的Python循环要消耗所有内存?
我想在一定时间内生成并保存一组元组。然而,我发现如果有足够的时间,这个程序似乎会消耗掉所有的内存 我试过两种方法。一个是删除新生成的变量,另一个是gc.collect()。但他们两人都没有成功。如果我只是生成而不保留元组,程序将消耗有限的内存 生成并保持:gk.py为什么我的Python循环要消耗所有内存?,python,Python,我想在一定时间内生成并保存一组元组。然而,我发现如果有足够的时间,这个程序似乎会消耗掉所有的内存 我试过两种方法。一个是删除新生成的变量,另一个是gc.collect()。但他们两人都没有成功。如果我只是生成而不保留元组,程序将消耗有限的内存 生成并保持:gk.py import gc import time from memory_profiler import profile from random import sample from sys import getsizeof @pro
import gc
import time
from memory_profiler import profile
from random import sample
from sys import getsizeof
@profile
def loop(limit):
t = time.time()
i = 0
A = set()
while True:
i += 1
duration = time.time() - t
a = tuple(sorted(sample(range(200), 100)))
A.add(a)
if not i % int(1e4):
print('step {:.2e}...'.format(i))
if duration > limit:
print('done')
break
# method 1: delete the variables
# del duration, a
# method 2: use gc
# gc.collect()
memory = getsizeof(t) + getsizeof(i) + getsizeof(duration) + \
getsizeof(a) + getsizeof(limit) + getsizeof(A)
print('memory consumed: {:.2e}MB'.format(memory/2**20))
pass
def main():
limit = 300
loop(limit)
pass
if __name__ == '__main__':
print('running...')
main()
生成并不保留:gnk.py
import time
from memory_profiler import profile
from random import sample
from sys import getsizeof
@profile
def loop(limit):
t = time.time()
i = 0
while True:
i += 1
duration = time.time() - t
a = tuple(sorted(sample(range(200), 100)))
if not i % int(1e4):
print('step {:.2e}...'.format(i))
if duration > limit:
print('done')
break
memory = getsizeof(t) + getsizeof(i) + getsizeof(duration) + \
getsizeof(a) + getsizeof(limit)
print('memory consumed: {:.2e}MB'.format(memory/2**20))
pass
def main():
limit = 300
loop(limit)
pass
if __name__ == '__main__':
print('running...')
main()
在cmd/shell中使用“mprof”(需要模块内存\u分析器)检查内存使用情况
mprof run my_file.py
mprof plot
gk.py的结果
memory consumed: 4.00e+00MB
Filename: gk.py
Line # Mem usage Increment Line Contents
================================================
12 32.9 MiB 32.9 MiB @profile
13 def loop(limit):
14 32.9 MiB 0.0 MiB t = time.time()
15 32.9 MiB 0.0 MiB i = 0
16 32.9 MiB 0.0 MiB A = set()
17 32.9 MiB 0.0 MiB while True:
18 115.8 MiB 0.0 MiB i += 1
19 115.8 MiB 0.0 MiB duration = time.time() - t
20 115.8 MiB 0.3 MiB a = tuple(sorted(sample(range(200), 100)))
21 115.8 MiB 2.0 MiB A.add(a)
22 115.8 MiB 0.0 MiB if not i % int(1e4):
23 111.8 MiB 0.0 MiB print('step {:.2e}...'.format(i))
24 115.8 MiB 0.0 MiB if duration > limit:
25 115.8 MiB 0.0 MiB print('done')
26 115.8 MiB 0.0 MiB break
27 # method 1: delete the variables
28 # del duration, a
29 # method 2: use gc
30 # gc.collect()
31 memory = getsizeof(t) + getsizeof(i) + getsizeof(duration) + \
32 115.8 MiB 0.0 MiB getsizeof(a) + getsizeof(limit) + getsizeof(A)
33 115.8 MiB 0.0 MiB print('memory consumed: {:.2e}MB'.format(memory/2**20))
34 115.8 MiB 0.0 MiB pass
gnk.py的结果
memory consumed: 9.08e-04MB
Filename: gnk.py
Line # Mem usage Increment Line Contents
================================================
11 33.0 MiB 33.0 MiB @profile
12 def loop(limit):
13 33.0 MiB 0.0 MiB t = time.time()
14 33.0 MiB 0.0 MiB i = 0
15 33.0 MiB 0.0 MiB while True:
16 33.0 MiB 0.0 MiB i += 1
17 33.0 MiB 0.0 MiB duration = time.time() - t
18 33.0 MiB 0.1 MiB a = tuple(sorted(sample(range(200), 100)))
19 33.0 MiB 0.0 MiB if not i % int(1e4):
20 33.0 MiB 0.0 MiB print('step {:.2e}...'.format(i))
21 33.0 MiB 0.0 MiB if duration > limit:
22 33.0 MiB 0.0 MiB print('done')
23 33.0 MiB 0.0 MiB break
24 memory = getsizeof(t) + getsizeof(i) + getsizeof(duration) + \
25 33.0 MiB 0.0 MiB getsizeof(a) + getsizeof(limit)
26 33.0 MiB 0.0 MiB print('memory consumed: {:.2e}MB'.format(memory/2**20))
27 33.0 MiB 0.0 MiB pass
我有两个问题:
如果有任何帮助,我们将不胜感激。鉴于集合的大小不断增加,它最终将消耗所有内存 估计值(从我的计算机):
查看python
generator
。你在用这些元组做什么?对a=tuple(排序(样本(范围(200),100))
不做任何操作。你只需这样做,然后忽略结果。我想生成并保留元组。“gk.py”(generate&keep)是当前的文件,“gnk.py”(generate¬keep)用于比较。当然,您正在消耗越来越多的内存。存储的元组越来越多。期望不消耗你所有的记忆最终表明你对记忆消耗的含义有一个糟糕的心理模型。正如@user2357112所说的,我不知道你想要什么。您正在生成元组并存储它们。你希望他们不带走记忆吗?你不是把它“保存在文件中”,而是把它保存在内存中。如果要将其保存在文件中,则需要将其写入文件。为什么在无限循环的内存中需要一堆随机元组?我已经编辑了我的问题。这次你能给点建议吗?对于问题2,你觉得什么奇怪?“gk.py”内存消耗会随着时间的推移而增加,或者“gnk.py”内存消耗不会增加,这一事实不要紧。我现在明白了。似乎集合“A”是动态分配内存的。这就是记忆增加的原因。
10 seconds of code running ~ 5e4 tuples saved to the set
300 seconds of code running ~ 1.5e6 tuples saved to the set
1 tuple = 100 integers ~ 400bytes
total:
1.5e6 * 400bytes = 6e8bytes = 600MB filled in 300s