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
SlipStupig
V2EX  ›  Python

关于 python 内存释放问题的一个疑惑

  •  
  •   SlipStupig · 2016-07-30 08:34:57 +08:00 · 5111 次点击
    这是一个创建于 3031 天前的主题,其中的信息可能已经有所发展或是发生改变。

    python 刚运行时只占用 3M 内存

    清单 1 :

    mt = {}
    for i in xrange(10000000):
        mt.setdefualt(i, i)

    这么时候我机器占用了 450MB 内存

    然后我执行: del mt
    内存占用 230MB,内存再也不是刚开始执行时候的 3MB 了,这个是为什么呢?

    15 条回复    2016-07-31 00:26:25 +08:00
    lll9p
        1
    lll9p  
       2016-07-30 08:53:37 +08:00
    试试

    import gc

    gc.collect()
    SErHo
        2
    SErHo  
       2016-07-30 08:54:02 +08:00 via iPad
    大部分的 malloc 实现和 Python 的对象分配都有用内存池, Python 对象回收不一定会调用 free ,即使调用 free 一些 malloc 实现也不会将内存还给操作系统。
    SlipStupig
        3
    SlipStupig  
    OP
       2016-07-30 09:22:13 +08:00
    @lll9p GC 对象返回的是 0 哦
    sujin190
        4
    sujin190  
       2016-07-30 10:09:21 +08:00
    整数缓存,每个整个只分配一次内存,但一旦分配了内存一般是不回收的,即使不使用了
    aec4d
        5
    aec4d  
       2016-07-30 10:14:35 +08:00   ❤️ 1
    http://stackoverflow.com/questions/1316767/how-can-i-explicitly-free-memory-in-python
    我比较喜欢这个回答 http://effbot.org/pyfaq/why-doesnt-python-release-the-memory-when-i-delete-a-large-object.htm
    It ’ s that you ’ ve created 5 million integers simultaneously alive, and each int object consumes 12 bytes. “ For speed ”, Python maintains an internal free list for integer objects. Unfortunately, that free list is both immortal and unbounded in size. floats also use an immortal & unbounded free list.

    邮件列表
    https://mail.python.org/pipermail/python-bugs-list/2004-October/025619.html

    意思就是 python 内部为了速度有一个整数缓存列表,添加了进去之后不知道怎么删除。。。。
    wangxn
        6
    wangxn  
       2016-07-30 10:16:23 +08:00 via Android
    学习了。 Python 的 GC 大部分时候都工作得很好。
    SlipStupig
        7
    SlipStupig  
    OP
       2016-07-30 10:49:32 +08:00
    @sujin190 你这么说还是有问题,为什么我删除了对象后内存少了很多,我再次跑清单 1 的时候,内存又变多了
    sujin190
        8
    sujin190  
       2016-07-30 12:11:15 +08:00
    @SlipStupig dict 对象不是还要占内存么?你删除了 dict 对象内存当然会释放一部分了
    SlipStupig
        9
    SlipStupig  
    OP
       2016-07-30 12:18:40 +08:00
    @sujin190 对象开始申请没占用那么大,删除后占用就变大了? 而且你说的是缓存啊,就是内存的数据应该还是存在的啊,为什么我继续添加整形数据的时候又变大了呢?(执行一样的语句)
    ruoyu0088
        10
    ruoyu0088  
       2016-07-30 12:38:22 +08:00
    Python3 解决了这个问题。
    lll9p
        11
    lll9p  
       2016-07-30 12:41:13 +08:00 via Android
    @SlipStupig @ruoyu0088 原来是版本不一样
    GeekGao
        12
    GeekGao  
       2016-07-30 17:21:03 +08:00   ❤️ 1
    这里涉及到整数对象池概念:
    python 的 VM 实现中,有大整数和小整数对象池的概念。
    首次使用大整数(>257 )时会分配大量内存块, PyIntObject 对象被销毁时,它所占有的内存并不会被释放,归还给系统,而是继续被 Python 保留着
    GeekGao
        13
    GeekGao  
       2016-07-30 17:24:28 +08:00
    对象池不是复用那些整数们,而是为了复用占据的内存空间,避免频繁创建和释放带来很大的性能开销
    GeekGao
        15
    GeekGao  
       2016-07-31 00:26:25 +08:00
    @zxc111 这种方法很讨巧, Python multiprocessing 模块 fork 一个 child process 开销很大的,估摸至少十几个到几十个 us 的时间就没了,如果是在 linux 平台可以使用 vfork 撸一个进程出来,降低 os.fork 调用的开销,让 child process 计算部分先行
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   985 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 22:52 · PVG 06:52 · LAX 14:52 · JFK 17:52
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.