python爆内存list_如何在python中截断列表? 分配新的list()是否会导致内存泄漏?...

假设我在python中有一个很大的列表my_list,我想截断它。 我可以通过删除它或将新列表分配给my_list来实现。 有什么更好的方法?

my_list = range(1, 10000)

方法1:

my_list = list()

print len(my_list) # prints 0

方法2:

del my_list[:]

print len(my_list) # prints 0

我觉得method2是执行此操作的更合适方法,对吗?

为什么要这么做?

我认为您使用的是C风格的假设。在C语言中,如果不小心,很容易造成内存泄漏。在Python中,很难创建内存泄漏,垃圾回收器每次触发时都会收集所有未引用的对象。您根本不应该自己考虑处理内存分配,这是不必要的,而不是Python的工作方式。考虑什么更有效就足够了。

@kampu Python垃圾收集器是Python的可选运行时组件。它的主要用途是收集无法访问的对象-主要是由于循环依赖。在正常使用中,引用计数机制用于分配对象内存。

@SylvainLeroux:实际上,这就是为什么我说垃圾收集-作为对引用计数的引用。但是,事实证明,引用计数不像我想的那样类似于GC(特别是在确切的时间重新分配引用计数降至1以下,而不是将其分批处理),所以我承认了这一点。

有两个相关的问题:stackoverflow.com/questions/1400608/和stackoverflow.com/questions/850795/clearing-python-lists

在内部,Python使用一种称为引用计数的机制来跟踪是否仍可访问数据。每当新的"变量"引用数据时,该数据的引用计数器就会增加。每次"变量"停止引用数据时,该数据的引用计数器都会减少。当参考计数器达到0时,数据将被删除(调用其"解除分配功能"):http://docs.python.org/2/c-api/refcounting.html

例如,这将创建一个"大"列表,该列表几乎在创建后就被删除,因为没有变量可以"增加"其引用计数器:

range(1, 10000)

这将创建一个新列表,允许您通过my_list进行引用并将列表的引用计数器设置为" 1"

my_list = range(1, 10000)

编写以下语句,现在将减少列表的引用计数器。假设您没有其他引用,该计数器达到0,因此该列表被删除。

my_list = None

最后一个例子:

my_list = range(1, 10000)

del my_list[:]

这将创建10000个项目的列表。参考计数器为" 1"。第二条语句删除列表中的10000个项目-但您仍然引用一个空列表。你看到区别了吗?

顺便说一句,引用计数是自动释放的一种很好的机制,它具有确定性的优点(与Java垃圾收集器相反)。但是,在一种情况下,引用计数不起作用:如果您有循环依赖项。对象A引用了引用对象A的对象B。在这种情况下,只要"圆"没有中断,A或B引用计数器都不会达到0。但是,我认为这超出了您的问题。无论如何,对于那些包含非主要循环依赖项的程序,Python有一个可选的垃圾收集器来释放此类循环。默认情况下,垃圾收集器处于启用状态。很容易检查:

>>> import gc

>>> gc.isenabled()

True

最后要说明的是,即使该垃圾收集器也受到限制,因为它不会使用终结器(__del__)释放包含对象的循环。有关以下内容的合理性,请参见以下链接:http://arctrix.com/nas/python/gc/

因此,无论是分配新列表还是使用Delete都没有关系。 谢谢。

请注意,实际上,可选垃圾回收器是自动使用的,并且运行良好,无需用户导入gc模块。 (您可能已经意识到了这一点,但是在答案文本中却并不明显。)循环引用很容易创建,并且不处理它们的系统不是很有用。

我已经更新了@ user4815162342的答案,以明确声明默认情况下启用了可选垃圾收集器。

删除是我的首选,因为两个操作几乎都需要相同的时间。并且del清除与列表关联的任何内存引用,并将其分配给新列表可能会导致旧内存无法正确清除。

这是模糊的:"可能导致旧内存无法正确清除。"。 您是说它没有被垃圾收集吗? 因为它的实际字节不会被清除,无论如何,直到将该内存分配给另一个对象(列表,元组等)之后,该对象才会初始化它。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值