Python实验:使用gc和memory_profiler探究内存管理

3

我使用Python 2.7.7运行了以下代码:

import gc
import memory_profiler

print memory_profiler.memory_usage()[0]
x = [i for i in range(10000000)]
print memory_profiler.memory_usage()[0]
x = None
print memory_profiler.memory_usage()[0]
gc.collect()
print memory_profiler.memory_usage()[0]

它生成了以下输出:
11.36328125
321.9140625
245.6171875
245.6171875

这里发生了什么?是什么导致内存使用量减少约25%?

你有一个大列表,你用x=None删除它。然而,你分配的所有int对象(即i)都在一个小对象缓存中,该缓存永远不会被释放,因为你将重复使用它们。 - Barry Scott
1个回答

1

这个文章应该会给你一个很好的想法。基本上,Python会有一些空闲列表内存,当它们被用完时,内存就会变成开销。例如:

import gc
import memory_profiler

print memory_profiler.memory_usage()[0]
x = [i for i in range(10000)]
print memory_profiler.memory_usage()[0]
x = None
print memory_profiler.memory_usage()[0]
gc.collect()
print memory_profiler.memory_usage()[0]

输出:

7.28515625
7.796875
7.796875
7.796875

但是当我使用一个非常巨大的列表运行您的代码时,结果是不同的,代码:

import gc
import memory_profiler


print memory_profiler.memory_usage()[0]
x = [i for i in range(10000000)]
print memory_profiler.memory_usage()[0]
x = None
print memory_profiler.memory_usage()[0]
gc.collect()
print memory_profiler.memory_usage()[0]

输出:

7.3515625
387.31640625
311.30859375
94.7890625

所以,如果我说的一切都是真的,如果它确实在使用完空闲的Python列表内存后导致了额外的开销,请尝试类似于post中释放内存:

import gc
import memory_profiler

def release_list(a):
   del a[:]
   del a


print memory_profiler.memory_usage()[0]
x = [i for i in range(10000000)]
release_list(x)
print memory_profiler.memory_usage()[0]
x = None
print memory_profiler.memory_usage()[0]
gc.collect()
print memory_profiler.memory_usage()[0]

输出:

7.34765625
318.3359375
318.3359375
96.3359375

很明显,当你将x = None赋值时,它会释放你通过一个非常大的列表初始化所引入的额外负担。通常在现实世界中,Python free list memory应该足以满足用户的需求,并且不会有任何区别。

其他资源:

  1. http://deeplearning.net/software/theano/tutorial/python-memory-management.html

  2. None在内存中的值是什么?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接