在很多情况下,你肯定不会再使用列表了,我希望现在应该释放内存
a = [11,22,34,567,9999]
del a
我不确定它是否真的释放内存,你可以使用
del a[:]
这实际上删除了列表 a 中的所有元素。
所以最好的释放方式是这样吗?
def realse_list(a):
del a[:]
del a
不太确定。需要你的意见。
顺便说一句,元组和集合怎么样?
在很多情况下,你肯定不会再使用列表了,我希望现在应该释放内存
a = [11,22,34,567,9999]
del a
我不确定它是否真的释放内存,你可以使用
del a[:]
这实际上删除了列表 a 中的所有元素。
所以最好的释放方式是这样吗?
def realse_list(a):
del a[:]
del a
不太确定。需要你的意见。
顺便说一句,元组和集合怎么样?
def release_list(a):
del a[:]
del a
永远不要这样做。Python 自动释放所有不再被引用的对象,所以一个简单的del a
方法确保如果列表没有在其他任何地方引用,列表的内存将被释放。如果是这种情况,那么各个列表项也将被释放(以及仅从它们引用的任何对象,依此类推),除非仍然引用了某些单独的项。
这意味着唯一del a[:]; del a
会发布更多内容的时间del a
是在其他地方引用列表时。这正是您不应该清空列表的时候:其他人仍在使用它!!!
基本上,您不应该考虑管理内存。相反,请考虑管理对对象的引用。在所有 Python 代码的 99% 中,Python 会在你上次需要它之后很快清理掉所有你不需要的东西,这没有问题。每当一个函数完成该函数中的所有局部变量“死亡”时,如果它们指向没有在其他任何地方引用的对象,它们将被删除,并且将级联到这些对象中包含的所有内容。
唯一需要考虑的是当你有一个大对象(比如一个巨大的列表)时,你用它做一些事情,然后你开始一个长时间运行(或内存密集型)的子计算,其中大对象子计算不需要。因为您有对它的引用,所以在子计算完成然后您返回之前,不会释放大对象。在这种情况下(并且只有这种情况),您可以del
在开始子计算之前显式引用大对象,以便可以更早地释放大对象(如果没有其他人正在使用它;如果调用者将对象传递给您并且调用者在您返回后仍然需要它,那么您会非常很高兴它没有被释放)。
正如@monkut 所指出的,在大多数情况下,您可能不应该过多担心内存管理。如果您确实有一个巨大的列表,您确定您现在已经完成并且它不会超出当前函数的范围,但是:
del a
只是删除你a
的那块内存的名字。如果其他一些功能或结构或其他任何东西仍然引用它,它不会被删除;如果此代码在名称下唯一引用该列表a
并且您使用的是 CPython,则引用计数器将立即释放该内存。其他实现(PyPy、Jython、IronPython)可能不会立即杀死它,因为它们有不同的垃圾收集器。
因此,函数中的del a
语句realse_list
实际上并没有做任何事情,因为调用者仍然有一个引用!
del a[:]
正如您所注意到的,将从列表中删除元素,因此可能会删除大部分内存使用。
您可以the_set.clear()
使用集合来实现类似的行为。
你可以对元组做的所有事情,因为它们是不可变的,del the_tuple
希望没有其他人引用它——但你可能不应该有巨大的元组!
Python 使用引用计数来管理其资源。
import sys
class foo:
pass
b = foo()
a = [b, 1]
sys.getrefcount(b) # gives 3
sys.getrefcount(a) # gives 2
a = None # delete the list
sys.getrefcount(b) # gives 2
在上面的例子中,当你把 b 放入一个列表时,它的引用计数会增加,正如你所看到的,当你删除列表时,b 的引用计数也会减少。所以在你的代码中
def release_list(a):
del a[:]
del a
是多余的。
总之,您需要做的就是将列表分配给 None 对象或使用 del 关键字从属性字典中删除列表。(又名,解除名称与实际对象的绑定)。例如,
a = None # or
del a
当对象的引用计数变为零时,python 将为您释放内存。为了确保对象被删除,您必须确保没有其他地方通过名称或容器引用该对象。
sys.getrefcount(b) # gives 2
如果sys.getrefcount给你 2,这意味着你是唯一拥有对象引用的人,并且当你这样做时
b = None
它将从内存中释放出来。
如果您担心数据类型的内存管理和性能,为什么不使用链接双队列之类的东西。
首先,它的内存占用分散在内存之外,因此您不必立即分配大量连续内存。
其次,您将看到更快的入队和出队访问时间,因为与标准列表不同,当您删除一个中间元素时,无需在索引中滑动列表的其余部分,这在大型列表中需要时间。
我还应该注意,如果您只使用整数,我建议您查看二进制堆,因为您会看到 O(log^2n) 访问时间,而列表的访问时间大多为 O(N)。
如果您需要释放列表的内存,保留列表的名称,您可以简单地写a=[]