首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >关于dict和list的python内存回收

关于dict和list的python内存回收
EN

Stack Overflow用户
提问于 2013-06-07 20:32:24
回答 2查看 163关注 0票数 1

最近,我对python的内存管理感到困惑。首先是dict,假设我有一个复合dict对象,如下所示

代码语言:javascript
复制
d = {id1: {'x': 'a', 'y': [1,2,3], 'z': {'k', 'v'}}, id2: {...}}

如果我调用del,

代码语言:javascript
复制
del d[id1]

did1和did1会一起回收吗?

第二个是关于列表,我从here上读到了答案,所以我尝试了一下。以下是我的代码

代码语言:javascript
复制
import sys
import gc
import time
from collections import defaultdict 
from pprint import pprint 

def f():
    d = defaultdict(int) 
    objects = gc.get_objects() 
    for o in objects: 
        d[type(o)] += 1
    x = d.items()
    x = sorted(x, key=lambda i: i[1], reverse=True)
    pprint(x[:5]) 

def loop():
    while True:
        leaked = [[x] for x in range(100)]
        f()
        time.sleep(0.1)

当范围是100时,函数f确实显示列表在增加,但当我将范围修改为1000时,没有什么可更改的,列表的数量保持不变。谁能告诉我出了什么问题?

EN

回答 2

Stack Overflow用户

发布于 2013-06-07 20:35:27

del移除对当前名称空间中对象的引用。在Cpython中,当对象的引用计数达到0时,python将可以将其用于未来的对象(它不一定会返回到操作系统)。

考虑一下:

代码语言:javascript
复制
a = []
b = a
del a #The list doesn't get freed because `b` is still a reference to that list

在您的场景中,当您使用del d[id1]时,您删除了对(内部)字典的引用。因为它持有一堆对其他对象的引用,所以这些对象中的每个对象现在少了一个引用。如果它们的引用计数达到0,它们将被收集,并且它们持有引用的每个对象的引用计数都将减少,依此类推。

票数 5
EN

Stack Overflow用户

发布于 2013-06-07 20:36:01

“did1和did1将一起回收吗?”

假设没有任何其他内容引用该字典或它的内容,那么所有这些都会同时转到引用计数0。但是,不能保证会立即收集其中任何一项。

"....Anybody能告诉我出了什么问题吗?“

Python缓存低整数对象,因此它们将始终被引用:

http://docs.python.org/2/c-api/int.html -“当前实现为-5到256之间的所有整数保留了一个整数对象数组,当您在该范围内创建一个整数时,实际上只是返回对现有对象的引用。”

这也许可以解释你所看到的行为。不使用范围(100)中的x,而是创建匿名对象,例如

代码语言:javascript
复制
leaked = [object() for x in range(100)]
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16984234

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档