900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > python的super super easy教程 | 垃圾回收 引用计数 深拷贝和浅拷贝

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

时间:2021-03-18 11:20:10

相关推荐

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

input最好是放在函数外面range(i)表示从0到(i-1)函数的作用:接收一个参数 返回一个参数python的内存管理 (常见的面试题)python的内存机制:以引用计数为主,分代回收,标记清除为辅的垃圾回收方式,以及对小整型进行缓存以及简单字符驻留的内存池机制内存管理:怎么去回收?python是动态类型语言对象是存储在内存中的实体a=1000(a是对象名 1000是对象)对象名只是指向这一对象的引用引用和对象分离,是动态类型的核心引用可以随时指向一个新的对象(内存地址会不一样)python的引用计数:a=500在内存中存储的是一个对象 这个对象包括(引用技术,int,500)引用计数:每个对象维护一个ob_ref字段(引用技术字段),用来记录该对象当前被引用的次数每次新的引用指向该对象时,它的引用计数ob_ref+1每当该对象的引用计数失效,就减1一旦对象的引用技数为0,该对象就被回收(销毁对象),该对象占用的内存就被释放怎么看你的引用计数嘞?from sys import getrefcounta=1000getrefcount(a) 出现的结果是2 实际的结果应该是1因为getrefcount会创建一个临时的指针指向a 于是我们得到的结果比实际的结果多1d=1000 e=1000 这两个指向的不是同一个对象d=e=1000 这两个才是同一个对象但是当循环引用时:x=[1]y=[2]x.append(y)y.append(x)getrefcount(x) 结果时3getrefcount(y) 结果为3(del为删除引用)del x 引用计数-1del y 引用计数-1x和y的引用计数都没有归0 空间不会被释放 但是已经调动不了了根据引用计数的规律,出现循环引用的情况,内存是无法通过引用计数来释放这种情况就会造成内存泄漏内存泄漏:有一部分内存被占用无法释放,进程又无法访问(占着茅坑不拉屎)内存泄漏会造成内存溢出(内存溢出--OOM:内存不够,程序需要的内存大于系统空闲内存)引用计数优点:简单 实时性缺点:维护引用计数消耗资源循环引用的时候 无法回收垃圾回收:gc机制:效率问题:垃圾回收时,python不能进行其他的任务,大大降低python的工作效率于是当python运行时,会记录其中分配对象和取消分配对象的次数。当两者的差值高于某个阈值时,垃圾回收才会启动import gcprint gc.get_threshold() 查看垃圾回收的阈值得到(700,10,10)--》阈值为700 后面两个10表示分代回收三种情况出发垃圾回收:1.调用gc.collect()手动垃圾回收import gcgc.collect() 进行垃圾回收2.gc到达阈值的时候3.程序退出时分代回收:(启用垃圾回收的时候确定扫描哪些对象的)这一策略的基本假设是:存活时间越久的对象,越不可能在后面的程序中变成垃圾。• Python将所有的对象分为0,1,2三代。• 所有的新建对象都是0代对象。• 当某一代对象经历过垃圾回收,依然存活,那么它就被归入下一代对象。• 垃圾回收启动时,一定会扫描所有的0代对象。• 如果0代经过一定次数垃圾回收,那么就启动对0代和1代的扫描清理。• 当1代也经历了一定次数的垃圾回收后,那么会启动对0,1,2,即对所有对象进行扫描(后面两个10 代表0代经历10次之后才扫1代 1代经历10次之后才扫2代)标记清除:(主要解决循环引用的)标记-清除机制,顾名思义,首先标记对象(垃圾检测),然后清除垃圾(垃圾回收)。主要用于解决循环引用。1. 标记:活动(有被引用), 非活动(可被删除)2. 清除:清除所有非活动的对象内存池机制:内存池,预先创建好一个整型池 [-5,256]字符串驻留区:字符串没有特殊字符且长度不是特别大的情况 或者单个字符的情况下,会存放在字符串驻留区如果多个字符且有特殊字符的情况下就不会放在字符串驻留区str1="abc"或者“#”getrefcount(str1) 输出为2str2="abc"或者“#”getrefcount(str1) 输出为3说明两个的id都是一样的str1=“123@123”str2=“123@123”这2个的id地址一样深拷贝和浅拷贝:(不属于内存管理)(容器包容器的情况且里面是是可变数据类型的情况才有影响)只会发生在容器类型里面包含其他可变容器类型的情况浅拷贝可能会造成修改拷贝之后的值(内层容器的值)。会改变原来的值浅拷贝只会拷贝第一层(外面第一层容器)的地址(也就是b拷贝的是引用的地址,不会拷贝值)a={"name":"sc","score":[80,90,100]}b=a.copy()b["score"].append(110)a,b都会变成{"name":"sc","score":[80,90,100,110]}a,b的id是不一样的 但是a["score"]和b["score"]是一样的拷贝的都是地址 {“name的地址”:“sc的地址”,“score的地址”:“列表的地址”}lst=[[]]*3这也是浅拷贝的一种lst=[[]]*3 得到[[],[],[]]lst[0].append(1) 得到[[1],[1],[1]]深拷贝不会发生这个情况深拷贝就是拷贝每一层地址import copya={"name":"sc","score":[80,90,100]}b=copy.deepcopy(a)拷贝的是:{"新的name":"新的sc","新的score":新的列表}这样a["score"]和b["score"]的id是不一样的只有用copy.deepcopy才是深拷贝 其他都是浅拷贝

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。