我最近看到了这篇关于Python内存分配的文章:http://deeplearning.net/software/theano/tutorial/python-memory-management.html
在这个页面上,它描述了Python的内存使用情况,并且有一个例子展示了整数列表的深度复制。我在Python 2.7上进行了基准测试。
Line # Mem usage Increment Line Contents
================================================
4 28.051 MiB 0.000 MiB @profile
5 def function():
6 59.098 MiB 31.047 MiB x = list(range(1000000)) # allocate a big list
7 107.273 MiB 48.176 MiB y = copy.deepcopy(x)
8 99.641 MiB -7.633 MiB del x
9 99.641 MiB 0.000 MiB return y
直接删除 x 只会删除 x 和所有指向 x 的整数引用,对吧?
这样做也无济于事(那么 del x 和 del x[:] 有什么区别呢?):
Line # Mem usage Increment Line Contents
================================================
4 28.047 MiB 0.000 MiB @profile
5 def function():
6 59.094 MiB 31.047 MiB x = list(range(1000000)) # allocate a big list
7 107.270 MiB 48.176 MiB y = copy.deepcopy(x)
8 99.637 MiB -7.633 MiB del x[:]
9 99.637 MiB 0.000 MiB return y
相对于深拷贝而言,如果我使用浅拷贝,在删除后,似乎当新创建x时内存会恢复到先前的状态。
Line # Mem usage Increment Line Contents
================================================
4 28.039 MiB 0.000 MiB @profile
5 def function():
6 59.090 MiB 31.051 MiB x = list(range(1000000)) # allocate a big list
7 66.895 MiB 7.805 MiB y = copy.copy(x)
8 59.262 MiB -7.633 MiB del x[:]
9 59.262 MiB 0.000 MiB return y
对于字典:
Line # Mem usage Increment Line Contents
================================================
4 28.051 MiB 0.000 MiB @profile
5 def function():
6 100.523 MiB 72.473 MiB x = dict((e, e) for e in xrange(1000000))
7 183.398 MiB 82.875 MiB y = copy.deepcopy(x)
8 135.395 MiB -48.004 MiB del x
9 135.395 MiB 0.000 MiB return y
对于列表的列表(与整数列表相比,我假设del x或del x[:]仅删除堆上的那个大数组列表?):
Line # Mem usage Increment Line Contents
================================================
4 28.043 MiB 0.000 MiB @profile
5 def function():
6 107.691 MiB 79.648 MiB x = [[] for _ in xrange(1000000)]
7 222.312 MiB 114.621 MiB y = copy.deepcopy(x)
8 214.680 MiB -7.633 MiB del x[:]
9 214.680 MiB 0.000 MiB return y
所以我想问:
- 如果没有方法可以回收整数占用的内存,整数也是一个对象,为什么内存完全不会被释放?只是整数无法被释放吗?或者浮点数和字符串也一样?对象引用也是如此吗?
- 为什么内存中有-7 MB?这是因为作为数组列表实现的列表已经从堆中释放了吗?
- 无论是列表还是字典,del x 只能释放数据结构本身(我的意思是数组列表结构或字典结构),但整数和对象引用可以被标记为未使用,但不会返回给系统吗?
那么在这个例子中,如何释放所有底层的列表?是否有方法可以实现?
Line # Mem usage Increment Line Contents
================================================
4 28.047 MiB 0.000 MiB @profile
5 def function():
6 248.008 MiB 219.961 MiB x = [list(range(10)) for _ in xrange(1000000)]
7 502.195 MiB 254.188 MiB y = copy.deepcopy(x)
8 494.562 MiB -7.633 MiB del x[:]
9 494.562 MiB 0.000 MiB return y