V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
invite
V2EX  ›  Python

新人求教: Python 删除 dict 一个 item 后,内存不释放的?

  •  
  •   invite · 2015-08-01 12:33:04 +08:00 · 8028 次点击
    这是一个创建于 3401 天前的主题,其中的信息可能已经有所发展或是发生改变。

    控制dict最大条目数量,然后不断的对dict增删该,发现内存不断增长。。。。

    del dict[key] 以后,内存不释放的啊?

    用gc也没用,内存一直增长。

    10 条回复    2015-08-03 15:16:01 +08:00
    zhyu
        1
    zhyu  
       2015-08-01 12:58:25 +08:00 via iPhone
    不释放的。你可以建个新dict把旧dict拷过去
    invite
        2
    invite  
    OP
       2015-08-01 13:00:45 +08:00
    @zhyu 那旧的dict拷贝过去了,旧的会被释放掉么?
    xiazi
        3
    xiazi  
       2015-08-01 13:00:49 +08:00
    如果能确认被del的没有在其他地方被引用的话, 先清理缓存后再gc:
    import sys, gc
    sys._clear_type_cache()
    gc.collect()
    twistoy
        4
    twistoy  
       2015-08-01 13:09:48 +08:00
    是不会释放的。因为删除了一个item之后,还要保证hash的探测链是完整的,所以那个entry只是被标记成了空,但并没有被删除掉,这部分不在gc的范围之内的。
    ruoyu0088
        5
    ruoyu0088  
       2015-08-01 18:16:07 +08:00
    你是说字典不释放空间还是被删除的对象不被释放,如果是对象不被释放,也许还有别的引用。你可以用getrefcount()查看引用计数,如果计数为2,那么删除该对象,它就会被回收:

    import gc
    import sys
    o = object()
    d = {"a": object(), "b":o}

    print sys.getrefcount(d["a"])
    print sys.getrefcount(d["b"])
    invite
        6
    invite  
    OP
       2015-08-01 21:15:14 +08:00
    @ruoyu0088

    字典里原来的对象没有释放。对象从字典删除后,打印出来计数器为2,但是内存一直增长。
    不知道有没有什么工具可以看到底是什么原因引起的?
    invite
        7
    invite  
    OP
       2015-08-01 21:20:30 +08:00
    @twistoy 啊?那如果是这样的话,dict不是不适合经常增删改的了?
    Feiox
        8
    Feiox  
       2015-08-01 21:53:26 +08:00
    为什么我测试的,完全不存在楼主遇到的问题,版本 Py 3.4,代码如下:
    a = {}

    while True:
    key = int(random.random() * 1000000)
    a[key] = [time.time()] * 10000000
    del a[key]
    22too
        9
    22too  
       2015-08-02 12:33:54 +08:00
    个人做法,一般字典用完,在初始换一次,初始换成空字典。
    a = dict ()
    a [123] = "asdf"
    a = dict()
    fatelei
        10
    fatelei  
       2015-08-03 15:16:01 +08:00
    del dict[key],只是把对应 key-value 的 entry 删除掉,dict本身的内存如果不满足 garbage collector 回收的条件,内存是不会被释放的,还是检查一次,dict中的 key-value 为啥会让内存不断增长吧。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   931 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 21:30 · PVG 05:30 · LAX 13:30 · JFK 16:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.