在许多情况下,您肯定不会再使用该列表,因此希望立即释放内存。
a = [11,22,34,567,9999] del a
我不确定上面的方法是否真的释放了内存。你可以用途:
del a[:]
它实际上删除了列表A中的所有元素。这是释放记忆的最好方法吗?
def realse_list(a): del a[:] del a
关于元组和集合,我也有同样的问题。
5ktev3wc1#
def release_list(a): del a[:] del a
千万不要这样做。Python会自动释放所有不再被引用的对象,所以一个简单的del a确保了如果列表没有被其他地方引用,那么列表的内存也会被释放。如果是这种情况,那么单个列表项也会被释放(以及仅从它们引用的任何对象,依此类推),除非仍引用了某些单独的项。这意味着只有del a[:]; del a自己释放了多于del a的时候,这个列表被其他地方引用了。这正是你 * 不 * 应该清空列表的时候:别人还在用!!!基本上,你不应该考虑管理内存块。相反,考虑管理对对象的引用。在99%的Python代码中,Python会在你最后一次需要它之后很快清理掉你不需要的所有东西,而且没有任何问题。每次一个函数完成该函数中的所有局部变量“死亡”时,如果它们指向的对象在其他任何地方都没有被引用,它们将被删除,这将级联到这些对象中包含的所有内容。只有当你有一个大的物体时,你才需要考虑它(比如说一个巨大的列表),你用它做一些事情,然后你开始一个长期运行的(或者内存密集型)子计算,其中子计算 * 不 * 需要大对象。因为您有对它的引用,直到子计算完成然后你返回时,大对象才会被释放。(且 * 仅 * 是这种情况),您可以在开始子计算之前显式地del您对大对象引用,以便可以更早地释放大对象(如果没有其他人正在使用它;如果调用者将对象传递给您,而调用者在您返回后仍然需要它,您会非常**高兴它没有被释放)。
del a
del a[:]; del a
del
ztmd8pv52#
正如@monkut所指出的,在大多数情况下,你可能不应该太担心内存管理。如果你有一个巨大的列表,你肯定你已经完成了 * 现在 *,它不会离开当前函数的作用域一段时间,但:del a只是删除你的名字a,如果其他函数或结构或任何东西仍然引用它,它不会被删除;如果这段代码在名称a下有对该列表的唯一引用,并且您使用的是CPython,则引用计数器将立即释放该内存。其他实现(PyPy、Jython、IronPython)可能不会立即杀死它,因为它们有不同的垃圾收集器。因此,realse_list函数中的del a语句实际上并不执行任何操作,因为调用方仍然有一个引用!正如您所注意到的,del a[:]将从列表中删除元素,从而可能删除其大部分内存使用。您可以对集合执行the_set.clear()以获得类似的行为。由于元组是不可变的,所以你能做的就是del the_tuple,并希望没有其他人引用它--但你可能不应该有巨大的元组!
a
realse_list
the_set.clear()
del the_tuple
zrfyljdw3#
Python使用Reference Count来管理它的资源。
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的引用计数会增加,正如你所看到的,当你删除列表时,b的引用计数也会减少。
是多余的。总之,您需要做的就是将列表分配给None对象,或者使用del关键字从属性字典中删除列表(也就是将名称从实际对象中解除绑定)。例如,
a = None # or del a
当一个对象的引用计数为零时,python会为你释放内存,为了确保这个对象被删除,你必须确保没有其他地方通过名称或容器引用这个对象。
sys.getrefcount(b) # gives 2
如果sys.getrefcount给您2,则意味着您是唯一拥有该对象引用的人,并且当您拥有该对象引用时
b = None
它将从内存中释放。
lsmepo6l4#
如果你担心内存管理和数据类型的性能,为什么不使用像链接双队列这样的东西呢?首先,它的内存足迹是分散的,所以你不必马上分配一大块连续的内存。其次,您将看到入队和出列的访问时间更快,因为与标准列表不同,当您删除中间元素时,不需要在索引中滑动列表的其余部分,这在大型列表中需要时间。如果你只使用整数,我建议你研究一下二进制堆,因为你会看到O(log^2n)的访问时间,而列表的访问时间大多是O(N)。
sf6xfgos5#
如果需要释放list的内存,保留list的名称,只需编写a=[]
a=[]
5条答案
按热度按时间5ktev3wc1#
千万不要这样做。Python会自动释放所有不再被引用的对象,所以一个简单的
del a
确保了如果列表没有被其他地方引用,那么列表的内存也会被释放。如果是这种情况,那么单个列表项也会被释放(以及仅从它们引用的任何对象,依此类推),除非仍引用了某些单独的项。这意味着只有
del a[:]; del a
自己释放了多于del a
的时候,这个列表被其他地方引用了。这正是你 * 不 * 应该清空列表的时候:别人还在用!!!基本上,你不应该考虑管理内存块。相反,考虑管理对对象的引用。在99%的Python代码中,Python会在你最后一次需要它之后很快清理掉你不需要的所有东西,而且没有任何问题。每次一个函数完成该函数中的所有局部变量“死亡”时,如果它们指向的对象在其他任何地方都没有被引用,它们将被删除,这将级联到这些对象中包含的所有内容。
只有当你有一个大的物体时,你才需要考虑它(比如说一个巨大的列表),你用它做一些事情,然后你开始一个长期运行的(或者内存密集型)子计算,其中子计算 * 不 * 需要大对象。因为您有对它的引用,直到子计算完成然后你返回时,大对象才会被释放。(且 * 仅 * 是这种情况),您可以在开始子计算之前显式地
del
您对大对象引用,以便可以更早地释放大对象(如果没有其他人正在使用它;如果调用者将对象传递给您,而调用者在您返回后仍然需要它,您会非常**高兴它没有被释放)。ztmd8pv52#
正如@monkut所指出的,在大多数情况下,你可能不应该太担心内存管理。如果你有一个巨大的列表,你肯定你已经完成了 * 现在 *,它不会离开当前函数的作用域一段时间,但:
del a
只是删除你的名字a
,如果其他函数或结构或任何东西仍然引用它,它不会被删除;如果这段代码在名称a
下有对该列表的唯一引用,并且您使用的是CPython,则引用计数器将立即释放该内存。其他实现(PyPy、Jython、IronPython)可能不会立即杀死它,因为它们有不同的垃圾收集器。因此,
realse_list
函数中的del a
语句实际上并不执行任何操作,因为调用方仍然有一个引用!正如您所注意到的,
del a[:]
将从列表中删除元素,从而可能删除其大部分内存使用。您可以对集合执行
the_set.clear()
以获得类似的行为。由于元组是不可变的,所以你能做的就是
del the_tuple
,并希望没有其他人引用它--但你可能不应该有巨大的元组!zrfyljdw3#
Python使用Reference Count来管理它的资源。
在上面的例子中,当你把b放到一个列表中时,b的引用计数会增加,正如你所看到的,当你删除列表时,b的引用计数也会减少。
是多余的。
总之,您需要做的就是将列表分配给None对象,或者使用del关键字从属性字典中删除列表(也就是将名称从实际对象中解除绑定)。例如,
当一个对象的引用计数为零时,python会为你释放内存,为了确保这个对象被删除,你必须确保没有其他地方通过名称或容器引用这个对象。
如果sys.getrefcount给您2,则意味着您是唯一拥有该对象引用的人,并且当您拥有该对象引用时
它将从内存中释放。
lsmepo6l4#
如果你担心内存管理和数据类型的性能,为什么不使用像链接双队列这样的东西呢?
首先,它的内存足迹是分散的,所以你不必马上分配一大块连续的内存。
其次,您将看到入队和出列的访问时间更快,因为与标准列表不同,当您删除中间元素时,不需要在索引中滑动列表的其余部分,这在大型列表中需要时间。
如果你只使用整数,我建议你研究一下二进制堆,因为你会看到O(log^2n)的访问时间,而列表的访问时间大多是O(N)。
sf6xfgos5#
如果需要释放list的内存,保留list的名称,只需编写
a=[]