• python垃圾回收机制
    • 垃圾回收机制要解决的问题
      • 内存泄漏
      • 悬空指针
    • 引用计数
      • 定义
      • 环形链表中所存放数据的相同点和不同点
      • 无法解决循环引用问题
    • 标记清除
      • 原理:
      • 存在查找活动对象效率低下的问题
    • 隔代回收
      • 原理
  • 猴子补丁
    • 定义
    • 猴子补丁的使用
    • 缺点
  • python反射机制
    • 定义
    • 主要包含四个方法
    • 应用场景
  • python 自省机制
    • 定义
    • 常见的自省机制
      • dir()
      • type( )
      • id( )
      • hasattr( )
      • getattr( )
      • isinstance( )
      • callable( )
      • inspect模块

python垃圾回收机制

python采用以引用计数为主,标记清除和隔代回收为辅的垃圾回收机制。(具体的内容参考------> python垃圾回收机制;博主解释的非常清晰易懂,在这里只是对该博客做一个学习笔记,方便本人日后复习。)

垃圾回收机制要解决的问题

内存泄漏

  由于一个长期持有的对象不断地往一个dict(字典)或者list对象中添加新的对象,而又没有及时释放,就会导致这些对象占用的内存越来越多。

常见的分析工具:

  1. gc
  2. objgraph
  3. memory.profiler
  4. tracemalloc
  5. filprofiler
  6. pympter

悬空指针

定义:
  主要是在C语言中,指针可以指向内存,如果这块内存稍后被操作系统回收,但是当前指针仍然指向这块内存,此时该指针就是悬空指针。

解决办法:一旦指针被释放就将指针赋值为NULL

野指针(补充):
  定义:不确定指针的具体指向,主要指向未初始化的指针。野指针的危害比悬空指针的危害还要大。

例如:Void *p;
解决办法:赋初值 Void *p = NULL

引用计数

定义

  • 在python中维护了一个refchain的双向环状链表(这个链表中存储创建的所有对象),在运行程序时,每创建一个对象会根据数据类型的不同,找到对应的结构体,根据结构体中的字段,将新创建的对象加入这个环形链表中;
  • 而每种类型的对象中,都有一个ob_refcnt(默认是1)引用计数器的值,它维护者引用的个数+1,-1,最后当引用计数器变为0时,则进行垃圾回收(对象销毁、refchain中移除)。

环形链表中所存放数据的相同点和不同点

  • 相同点,都包含四部分内容(指向上一个对象的指针,指向下一个对象的指针、类型、引用的个数)
# 内部会创建一些数据,【指向上一个对象的指针、指向下一个对象的指针、类型、引用的个数】
age = 18    # 整形对象
# 内部会创建一些数据,【指向上一个对象的指针、指向下一个对象的指针、类型、引用的个数】
hobby = ["吸烟","喝酒","烫头"]   # 列表对象
  • 不同点:不同的数据类型会创建不同的值:
# 内部会创建一些数据,【指向上一个对象的指针、指向下一个对象的指针、类型、引用的个数、val=18】
age = 18    # 整型对象
# 内部会创建一些数据,【指向上一个对象的指针、指向下一个对象的指针、类型、引用的个数、items=元素、元素的个数】
hobby = ["抽烟","喝酒","烫头"]   # 列表对象
data = 3.14
内部会创建:_ob_next = refchain中的上一个对象_ob_prev = refchain中的后一个对象ob_refcnt = 1     引用个数ob_type= float    数据类型ob_fval = 3.14

无法解决循环引用问题

v1 = [1,2,3]        # refchain中创建一个列表对象,由于v1=对象,所以列表引对象用计数器为1.
v2 = [4,5,6]        # refchain中再创建一个列表对象,因v2=对象,所以列表对象引用计数器为1.
v1.append(v2)        # 把v2追加到v1中,则v2对应的[4,5,6]对象的引用计数器加1,最终为2.
v2.append(v1)        # 把v1追加到v1中,则v1对应的[1,2,3]对象的引用计数器加1,最终为2.del v1    # 引用计数器-1
del v2    # 引用计数器-1最终v1,v2引用计数器都是1

标记清除

引用计数机制无法解决循环引用问题,因此python引入标记-清除算法解决循环引用问题。

原理:

在python的底层,再去维护一个链表,在这个链表中专门去存放存在循环引用的对象(list/ dict/ tuple/ class),然后在某种情况下,扫描可能存在循环引用的链表中的每个元素,如果检查到循环引用,就让双方的引用计数减1,如果是0,则进行垃圾回收。

存在查找活动对象效率低下的问题

【标记清除(Mark—Sweep)】算法是一种基于追踪回收(tracing GC)技术实现的垃圾回收算法。它分为两个阶段:第一阶段是标记阶段,GC会把所有的『活动对象』打上标记,第二阶段是把那些没有标记的对象『非活动对象』进行回收。因此,在清除非活动对象之前必须顺序扫描整个堆内存,标记和清除的效率不高。

隔代回收

由于在标记-清除算法中,在清除非活动对象之前必须顺序扫描整个堆内存,标记和清除的效率不高,因此python又引入了隔代回收(或分代回收)

原理

根据弱代假说(年轻的对象通常死得也快,而老对象则很有可能存活更长的时间)将第二个链表(可能存在循环引用的链表),维护成3个环状双向的链表:

0代: 0代中对象个数达到700个,扫描一次。
1代: 0代扫描10次,则1代扫描1次。
2代: 1代扫描10次,则2代扫描1次。

频繁的处理零代链表中的新对象,可以将让Python的垃圾收集器把时间花在更有意义的地方:它处理那些很快就可能变成垃圾的新对象。同时只在很少的时候,当满足一定的条件,收集器才回去处理那些老变量。

猴子补丁

定义

monkey patch允许在运行期间动态修改一个类或模块(注意python中一切皆对象,包括类、方法、甚至是模块)功能就是动态的属性的替换。

猴子补丁的使用

class A:def func(self):print("Hi")def monkey(self):print("Hi, monkey")
a = A()
A.func=A.monkey   #在运行的时候,才改变了func
a.func()
'''运行结果
Hi, monkey
'''

缺点

因为猴子补丁破坏了封装,且容易导致程序与补丁代码的实现细节紧密耦合,所以只是临时的变通方案。

参考:python进阶-----猴子补丁

python反射机制

定义

把字符串映射到实例(对象)的变量或者实例(对象)的方法然后可以去执行调用、修改等操作。
核心:通过字符串去操作对象的属性和方法

主要包含四个方法

方法 意义
getattr(object,name[,default]) 通过name返回object的属性值,当属性不存在,返回default默认值,如果没有default,则抛出异常,name必须是字符串
setattr(object,name,value) 操作object的属性,如有则覆盖,不存在则新增
hasaattr(object,name) 判断对象是否有这个名字的属性,name必须为字符串,有返回True,不存在返回Felse
delattr(object,name) 当通过实例来删除属性时调用此方法

反射方法的查找路径:
对象本身__dict__---->class的__dict__---->继承的祖先类(直到object)的__dict__

Note: attributes 和 functions 都存在__dict__ 里面

应用场景

在项目开发中尤为重要,在不清楚方法或变量在对象中是否存在时,可以通过反射这个特殊的方法或机制来对对象中"未知的"变量或者方法进行操作。

  • 实例化对象进行反射
  • 类的反射
  • 模块间的反射
  • 通过字符串导入模块(从文件中读出的字符串,想转换成变量的名字)
  • 模拟FTP动态请求过程(将网络传输的字符串转换成变量的名字)

参考:python基础:反射(详解)
   python的反射
   python反射详解

python 自省机制

定义

在编程语言中,自省是指自我检查行为。检查某些事物以确定它是什么,它能做什么。

具体的来说,就是OPP(面向对象)语言在程序运行时,能够知道对象的类型,部分语言还能够知道对象所拥有的属性。

常见的自省机制

在python中,常见的自省(introspection)机制有许多,如:==dir()、type()、hasattr()、isinstance()==等,通过这些函数,我们可以在运行时得知对象的类型和属性。

dir()

它是用于自省的最重要的函数之一。它以列表的形式返回一个对象所拥有的全部属性和方法,如果dir()不传任何参数,默认是查找当前命名空间有什么对象。

a = 2333
print(dir(a))
# 输出省略...

当我们记不太清某个对象的某个方法的名字时,使用这个是非常有帮助的。

type( )

type()函数返回一个对象的类型。例如:

print(type('tigeriaf'))
# 结果输出为 <class 'str'>
print(type(2))
# 结果输出为 <class 'int'>
print(type([1, 2, 3]))
# 结果输出为 <class 'list'>

id( )

id()函数返回对象的唯一标识符,是一个整数,在CPython中id()函数用于获取对象的内存地址。例如:

print(id('tigeriaf'))
# 结果输出为 51064768

hasattr( )

虽然使用dir()函数会返回一个对象属性的列表,但我们有时候的需求只是判断一个对象是否含有某一个或者多个属性,这样,我们就可以使用hasattr()函数来完成,它返回一个bool值:

import json
print(hasattr(json, "dumps"))

getattr( )

使用hasattr()函数判断对象是否有某个属性值后,我们可以配合getattr()函数来获取其属性值:

print(getattr(json, "__path__"))

isinstance( )

使用isinstance()函数可以确定一个对象是否是某个特定类型或者定制类的实例:

class A:passclass B(A):passdef foo():passobj = B()print(isinstance(B,MethodType)) # 返回true,判断是否是类方法
print(isinstance(obj, A)) # true
print(isinstance(foo, FunctionType)) # 返回true,判断是否是函数

callable( )

使用callable()函数可以确定一个对象是否是可调用对象,比如函数对象,类对象等等,他们都是可调用的对象:

callable("23333") # false
callable(str) # true

inspect模块

inspect是Python的标准库,提供了更加强大的自省能力,提供了很多函数帮助获取对象的信息,例如模块、类、方法、函数、回溯、帧对象以及代码对象。
该模块提供了4种主要的功能:类型检查、获取源代码、检查类与函数、检查解释器的调用堆栈。

详解参考: Python强大的自省机制
      python的自省机制

python的几种重要机制(垃圾回收机制,猴子补丁,反射机制,自省机制)相关推荐

  1. python gc教程_python中的垃圾回收(GC)机制

    一.引用计数 Python 垃圾回收以引用计数为主,分代回收为辅.引用计数法的原理是每个对象维护一个ob_refcnt,用来记录对象被引用的次数,也就是用来追踪有多少个引用指向了对象,当发生以下四种情 ...

  2. python的super super easy教程 | 垃圾回收 引用计数 深拷贝和浅拷贝

    input最好是放在函数外面range(i)表示从0到(i-1)函数的作用:接收一个参数 返回一个参数python的内存管理 (常见的面试题)python的内存机制:以引用计数为主,分代回收,标记清除 ...

  3. 【深入理解Java虚拟机】自动内存管理机制——垃圾回收机制

      Java与C++之间有一堵有内存动态分配和垃圾收集技术所围成的"高墙",墙外面的人想进去,墙里面的人却想出来.C/C++程序员既拥有每一个对象的所有权,同时也担负着每一个对象生 ...

  4. python实现链表的删除_Python垃圾回收机制

    python作为一门解释型语言,以代码简洁易懂著称.我们可以直接对名称赋值,而不必声明类型.名称类型的确定.内存空间的分配与释放都是由python解释器在运行时进行的.python这一自动管理内存功能 ...

  5. python 类定义 垃圾_什么是python对象摧毁?python中的对象摧毁(垃圾回收)机制是什么?...

    在这篇文章之中我们来了解一下python对象摧毁(垃圾回收),对于刚刚接触到python这一编程语言的朋友来说,对于python对象摧毁(垃圾回收)的了解应该比较少,并且不清楚关于python垃圾回收 ...

  6. C++中垃圾回收机制中几种经典的垃圾回收算法

    前言 垃圾收集器是一种动态存储分配器,它自动释放程序不再需要的已分配的块,这些块也称为 垃圾 .在程序员看来,垃圾就是不再被引用的对象.自动回收垃圾的过程则称为 垃圾收集(garbage collec ...

  7. python入门系列:对象引用、垃圾回收、可变性

    Python中的变量是什么 引言 Python和java中的变量本质不一样,java的变量可以理解为一个盒子,用来容纳我们的对象,使用前要先声明它,好分配给我们合适的内存空间.Python的变量可以理 ...

  8. java垃圾回收机制_JVM的垃圾回收机制——垃圾回收算法

    一.Java垃圾回收机制 在java中,程序员是不需要显示的去释放一个对象的内存的,而是由虚拟机自行执行.在JVM中,有一个垃圾回收线程,它是低优先级的,在正常情况下是不会执行的,只有在虚拟机空闲或者 ...

  9. [流畅的Python][8][对象引用、可变性和垃圾回收]

    第8章 对象引用.可变性和垃圾回收 "你不开心,"白骑士用一种忧虑的声调说,"让我给你唱一首歌安 慰你吧--这首歌的曲名叫作 :<黑线鳕的眼睛>." ...

  10. Java 中的四种引用及垃圾回收策略

    Java 中有四种引用:强引用.软引用.弱引用.虚引用: 其主要区别在于垃圾回收时是否进行回收: 1.强引用 使用最普遍的引用.如果一个对象具有强引用,那就 类似于必不可少的生活用品,垃圾回收器绝不会 ...

最新文章

  1. AI 医生正式上岗了?AI 医疗结合迎爆发点!
  2. Java开发中最常犯的10个错误,你中招了吗?
  3. 证书在 Exchange 2007 Server 中的使用
  4. hdu-4549 M斐波那契数列 nyoj - 1000
  5. 常规循环引用内存泄漏和Closure内存泄漏
  6. 我的世界linux开服权限不足,我的世界路由器开服怎么获得超级管理员权限
  7. android拍照功能编程,android实现手机App实现拍照功能示例
  8. 战术网络安全检查表 | Symantec Connect
  9. c语言中错误为ffblk未定义,C语言中头文件及函数的含意的总分类
  10. settings.xml的配置
  11. 关于零基础学习web前端开发,有些过来经验分享
  12. 互联网运营数据分析(1):流量分析
  13. 【2020团体程序设计天梯赛】L2-3 完全二叉树的层序遍历(后序遍历转层次遍历)
  14. javascript在使用时要注意的东西
  15. HFSS初探日志(二)微波滤波器设计实例:微带发夹线滤波器
  16. 启用视口着色:在视图窗口实时显示灯光照明效果_daiding
  17. 论文代码复现 | 无人机与卡车联合配送(Python+Gurobi)(The flying sidekick traveling salesman problem)
  18. DevExpress 控件使用之XtraReport
  19. 让横向纵向分辨率都一致
  20. 我知道很多主播因为以前因为公会的名声不太好,或者不想签约被束缚等原因

热门文章

  1. C#应用程序界面开发进阶——高级窗体控件(5)——MonthCalender控件
  2. 最短路径问题 --- Dijkstra算法详解
  3. 全栈“食”代:用 Django + Nuxt 实现美食分享网站(一)
  4. Linux whoami 命令
  5. 苹果概念手机_苹果游戏概念手机:两个屏幕+侧滑盖颠覆性设计,不仅仅只有这些...
  6. 2021年全球锂电池负极材料行业发展现状、竞争格局及企业产能布局分析,全球市场头部企业均是本土企业「图」
  7. ibm cloud属于paas吗_研华成立WISE-Cloud智慧云平台联盟
  8. visio画卷积神经网络示意图_visio模型绘制(如何使用visio2013如何绘制UML图)
  9. 华为ax3怎么接光纤sc接口_华为路由器AX3与其他华为/荣耀路由器如何连接?
  10. 龙之谷微信该服务器已爆满,微信一区爆满 还能进吗