• Python深入之python内存管理机制(重点)


    关于python的存储问题

    (1)由于python中万物皆对象,所以python的存储问题是对象的存储问题,并且对于每个对象,python会分配一块内存空间去存储它

    (2)对于整数和短小的字符等,python会执行缓存机制,即将这些对象进行缓存,不会为相同的对象分配多个内存空间,如果对我讲的还不懂,说明你基础学的还不是和很好,可以去小编的Python交流.裙 :一久武其而而流一思(数字的谐音)转换下可以找到了,里面很多最新Python精讲的教程项目。

    (3)容器对象,如列表、元组、字典等,存储的其他对象,仅仅是其他对象的引用,即地址,并不是这些对象本身

    关于引用计数器

    (1)一个对象会记录着引用自己的对象的个数,每增加一个引用,个数加一,每减少一个引用,个数减一

    (2)查看引用对象个数的方法:导入sys模块,使用模块中的getrefcount(对象)方法,由于这里也是一个引用,故输出的结果多1

    (3)增加引用个数的情况:1.对象被创建p = Person(),增加1;2.对象被引用p1 = p,增加1;3.对象被当作参数传入函数func(object),增加2,原因是函数中有两个属性在引用该对象;4.对象存储到容器对象中l = [p],增加1

    (4)减少引用个数的情况:1.对象的别名被销毁del p,减少1;2.对象的别名被赋予其他对象,减少1;3.对象离开自己的作用域,如getrefcount(对象)方法,每次用完后,其对对象的那个引用就会被销毁,减少1;4.对象从容器对象中删除,或者容器对象被销毁,减少1

    (5)引用计数器用法:

    import sys
    class Person(object):
        pass
    p = Person()
    p1 = p
    print(sys.getrefcount(p))
    p2 = p1
    print(sys.getrefcount(p))
    p3 = p2
    print(sys.getrefcount(p))
    del p1
    print(sys.getrefcount(p))

    多一个引用,结果加1,销毁一个引用,结果减少1

    (6)引用计数器机制:利用引用计数器方法,在检测到对象引用个数为0时,对普通的对象进行释放内存的机制

    关于循环引用问题

    如果对我讲的还不懂,说明你基础学的还不是和很好,可以去小编的学习交流小天地python高薪就业(视频、学习路线、免费获取)​www.jianshu.com,里面很多最新Python精讲的教程项目。

    (1)循环引用即对象之间进行相互引用,出现循环引用后,利用上述引用计数机制无法对循环引用中的对象进行释放空间,这就是循环引用问题

    (2)循环引用形式:

    class Person(object):
        pass
    class Dog(object):
        pass
    p = Person()
    d = Dog()
    p.pet = d
    d.master = p

    即对象p中的属性引用d,而对象d中属性同时来引用p,从而造成仅仅删除p和d对象,也无法释放其内存空间,因为他们依然在被引用。深入解释就是,循环引用后,p和d被引用个数为2,删除p和d对象后,两者被引用个数变为1,并不是0,而python只有在检查到一个对象的被引用个数为0时,才会自动释放其内存,所以这里无法释放p和d的内存空间

    关于垃圾回收(底层层面--原理)

    (1)垃圾回收的作用:从经过引用计数器机制后还没有被释放掉内存的对象中,找到循环引用对象,并释放掉其内存

    (2)垃圾回收检测流程:

    一.任何找到循环引用并释放内存:1.收集所有容器对象(循环引用只针对于容器对象,其他对象不会产生循环引用),使用双向链表(可以看作一个集合)对这些对象进行引用;

    2.针对每一个容器对象,使用变量gc_refs来记录当前对应的应用个数;

    3.对于每个容器对象,找到其正在引用的其他容器对象,并将这个被引用的容器对象引用计数减去1;

    4.经过步骤3后,检查所有容器对象的引用计数,若为0,则证明该容器对象是由于循环引用存活下来的,并对其进行销毁

    二.如何提升查找循环引用过程的性能:

    由一可知,循环引用查找和销毁过程非常繁琐,要分别处理每一个容器对象,所以python考虑一种改善性能的做法,即分代回收。

    首先是一个假设--如果一个对象被检测了10次还没有被销毁,就减少对其的检测频率;基于这个假设,提出一套机制,即分代回收机制。

     

     

    通过这个机制,循环引用处理过程就会得到很大的性能提升

    关于垃圾回收时机(应用层面--重点)

    (1)自动回收:

     

     

    (2)手动回收:这里要使用gc模块中的collect()方法,使得执行这个方法时执行分代回收机制

    import objgraph
    import gc
    import sys
    class Person(object):
        pass
    class Dog(object):
        pass
    p = Person()
    d = Dog()
    p.pet = d
    d.master = p
    del p
    del d
    gc.collect()
    print(objgraph.count("Person"))
    print(objgraph.count("Dog"))

    其中objgraph模块的count()方法是记录当前类产生的实例对象的个数

    关于内存管理机制的总结(重点)

    综上所述,python的内存管理机制就是引用计数器机制和垃圾回收机制的混合机制

  • 相关阅读:
    《Redis内存数据库》Redis主复制集(主从复制)
    《Redis内存数据库》Redis消息模式
    《Redis内存数据库》redis配置文件说明
    《Redis内存数据库》Redis事务
    《Redis内存数据库》Redis持久化实现方式和原理
    《Redis内存数据库》Redis基本操作命令
    《Redis内存数据库》Redis权限管理
    yum install 与 yum groupinstall 的区别
    LNMP卸载
    Vim配置 终端背景色配置
  • 原文地址:https://www.cnblogs.com/nanhe/p/12834579.html
Copyright © 2020-2023  润新知