zoukankan      html  css  js  c++  java
  • 垃圾回收机制详解

     

    1、垃圾回收机制详解

    1.1 引用计数

    引用计数表示的是一个变量被引用的次数

    例如:

    x = 10  # 直接引用,10的引用计数变为1
    print(id(x))
    y = x  # 直接引用,10的引用计数变为2
    z = x  # 直接引用,10的引用计数变为3
    print(id(x),id(y),id(z))

    这里提到了直接引用的概念,和它相对的还有间接引用.

    如果x在容器类型(如列表和字典)中被使用即10被间接引用了,间接引用同样会增加引用计数

    x = 10  # 直接引用,10的引用计数变为1
    l = ['a', 'b', x]  # 间接引用,10的引用计数变为2
    print(id(l[2]))  
    d = {'mmm': x}  # 间接引用,10的引用计数变为3
    print(id(d['mmm']))

    引用的显著特点即他们的id都相同

     

    在python中会自动将引用计数为0的变量值清除,回收其占有的内存空间,防止内存占用过高,这就是垃圾回收机制

     

     

    1.2 标记清除

    标记清除是一种用来解决循环引用时产生内存泄漏,即出现无法清除的变量值的方法.

    lis1=[1,2,3]
    lis2 = [2,3]
    lis1.append(lis2)   # 此时lis1能间接引用lis2
    lis2.append(lis1)   # 此时lis2能间接引用lis1
    print(lis1)
    print(lis2)
    del lis1    # 解除变量名lis1和变量值的关系
    del lis2    # 解除变量名lis2和变量值的关系
    # 此时lis1里的数据与lis2里的数据都无法通过直接或间接引用的方法得到
    # 但是之前列表内数据的引用计数不为0,他们还有间接引用的关系,无法直接被垃圾回收机制清除

    此时我们必须引入新的方法,即标记清除

    我们知道,变量名存放在栈中,变量值存放在堆内,python会在内存将满时使用标记清除,检测现存放在栈中的所有变量名,并对其标记为存活,接着进入堆内检测是否有和存活变量名完全无关的数据,一旦发 现就将它清除,这就是标记清除.

    可以以一个简单易于理解的例子来解释:栈内的变量名就像树的根,堆内的变量值就像树的枝干,一旦一 棵树根全部被清除,树就无法存活,这时就需要将没有根的枝干全部清除.

     

    1.3 分代回收

    了解了python的垃圾回收机制,我们就要考虑一个问题,那就是回收垃圾的频率问题,如果无时无刻对所有的变量值进行检测,会占用大量的内存,我们需要尽量降低python的扫描频率,提高垃圾回收的效率,python中使用了分代回收来解决这一难题.

    分代回收就是将变量值进行分代,分成使用频率不同的三代:新生代,中年代,老年代,

    新变量都为新生代,在过程中动态检测变量值,扫描频率新生代最高,老年代最低,扫描多次依旧存活的变量会进入中年代或者老年代,减少部分变量值的扫描次数,以此达到提高效率,降低占用内存的目的.

     

     

     

  • 相关阅读:
    PT100高精度测温电路 AD623+REF3030(转)
    STM32|4-20mA输出电路(转)
    串口通讯数据处理算法分析与实现(转)
    stm32_CAN总线知识(转)
    图像的灰度级和动态范围(转)
    图像bayer格式介绍以及bayer插值原理CFA(转)
    用oracle建表,必须注意Oracle 关键字(保留字)
    爬虫的定向爬取与垂直搜索
    开源的网络爬虫以及一些简介和比较
    SQL中的等号、IN、LIKE三者的比较
  • 原文地址:https://www.cnblogs.com/achai222/p/12421336.html
Copyright © 2011-2022 走看看