zoukankan      html  css  js  c++  java
  • python的内存管理

    python是如何进行内存管理的?
    3个方面:
    1.垃圾回收:当引用计数为0时,或两个变量相互引用,但其本身为已经为0(独立的引用环)
    2.引用计数:一个对象被创建时,就会创建一个引用计数。对象不再需要,且引用计数为0才会被垃圾回收
    3.内存池机制:每个对象都有独立的内存池,且对象之间的内存池不相互引用,对象之间不共享内存池,
    Python中所有小于256个字节的对象都使用pymalloc实现的分配器

    ******************************************************************************************************************************

    引用计数:

    python引用了一个机制:引用计数。
    python内部使用引用计数,来保持追踪内存中的对象,Python内部记录了对象有多少个引用,及引用计数

    在Python中,每个对象都有存有指向该对象的引用总数,即引用计数(reference count)。
    我们可以使用sys包中的getrefcount(),来查看某个对象的引用计数。需要注意的是,当使用某个引用作为参数,
    传递给getrefcount()时,参数实际上创建了一个临时的引用。因此,getrefcount()所得到的结果,会比期望的多1。

    (引用减少)
    某个对象的引用计数可能减少。比如,可以使用del关键字删除某个引用
    del也可以用于删除容器元素中的元素
    如果某个引用指向对象A,当这个引用被重新定向到某个其他对象B时,对象A的引用计数减少:
    from sys import getrefcount

    a = [1, 2, 3]
    b = a
    print(getrefcount(b))#3个

    a = 1
    print(getrefcount(b))#2个

    (引用增加)
    1.对象被创建:x=4
    2.另外的别人被创建:y=x
    3.被作为参数传递给函数:foo(x)
    4.作为容器对象的一个元素:a=[1,x,'33']
    变量更像是附在对象上的标签。当变量被绑定在一个对象上的时候,该变量的引用计数就是1
    在Python中,每个对象都有存有指向该对象的引用总数,即引用计数(reference count)。

    ***************************************************************************************************************

    对象的内存使用:

    a=1
    b=1
    a is b :true
    所有整数1的引用都指向同一对象。整数和短字符串使用赋值语句,也只是创造了新的引用,而不是对象本身
    长的字符串和其它对象可以有多个相同的对象,可以使用赋值语句创建出新的对象。

    对象引用对象:

    Python的一个容器对象(container),比如表、词典等,可以包含多个对象。实际上,
    容器对象中包含的并不是元素对象本身,是指向各个元素对象的引用。

    *******************************************************************************
    垃圾回收:

    a.自动回收:
    当Python运行时,会记录其中分配对象(object allocation)和取消分配对象(object deallocation)的次数。
    当两者的差值高于某个阈值时,垃圾回收才会启动。
    我们可以通过gc模块的get_threshold()方法,查看该阈值:
    import gc
    print(gc.get_threshold())
    返回(700, 10, 10),后面的两个10是与分代回收相关的阈值,后面可以看到。700即是垃圾回收启动的阈值。
    可以通过gc中的set_threshold()方法重新设置。

    b.分代回收

    Python将所有的对象分为0,1,2三代。所有的新建对象都是0代对象。当某一代对象经历过垃圾回收,依然存活,
    那么它就被归入下一代对象。垃圾回收启动时,一定会扫描所有的0代对象。如果0代经过一定次数垃圾回收,
    那么就启动对0代和1代的扫描清理。
    当1代也经历了一定次数的垃圾回收后,那么会启动对0,1,2,即对所有对象进行扫描。
    这两个次数即上面get_threshold()返回的(700, 10, 10)返回的两个10。也就是说,每10次0代垃圾回收,
    会配合1次1代的垃圾回收;而每10次1代的垃圾回收,才会有1次的2代垃圾回收。
    同样可以用set_threshold()来调整,比如对2代对象进行更频繁的扫描。
    import gc
    gc.set_threshold(700, 10, 5)

    c.孤立的引用环
    a = []
    b = [a]
    a.append(b)
    del a
    del b
    上面我们先创建了两个表对象,并引用对方,构成一个引用环。删除了a,b引用之后,
    这两个对象不可能再从程序中调用,就没有什么用处了。但是由于引用环的存在,
    这两个对象的引用计数都没有降到0,不会被垃圾回收。
    为了回收这样的引用环,Python复制每个对象的引用计数,可以记为gc_ref

    参考:http://www.cnblogs.com/vamei/p/3232088.html

  • 相关阅读:
    在Windows上搭建Git Server
    Android Studio Intent使用(显式、隐式)
    Android Studio2.0 教程从入门到精通Windows版
    Android Studio2.0 教程从入门到精通Windows版
    【转】自动化框架中引入ExtentReport美化报告
    阿里巴巴Java开发规约IDEA插件安装及使用
    13位时间戳与格式化日期之间的转换实现
    计算机基础知识试题及答案
    构建最基础的Spring项目及所需要的jar包
    (二)SpringMVC+mybatis实践
  • 原文地址:https://www.cnblogs.com/qieyu/p/7805714.html
Copyright © 2011-2022 走看看