Ⅰ 猴子补丁
一种编程的方式,直接把程序的某一个功能换成另外的一个功能
就是纯粹的替换功能,在使用该功能之间操作
import json
import ujson # pip3 install ujson
def monkey_patch():
json.__name__ = ujson.__name__
json.dumps = ujson.dumps
json.loads = ujson.loads
Ⅱ 垃圾回收机制
引用计数:一个变量值的引用计数为0时,才会被当成垃圾回收
name = 'shuai'
del name
# 变量'shuai'引用计数为0了
标记
通俗的讲就是:栈区相当于根,凡是从根出发可以访问到达的变量(直接或间接),都称之为有根之人,有根之人当活,无根之人当死(主要用来解决循环引用)
# 如下我们定义了两个列表,简称列表1与列表2,变量名l1指向列表1,变量名l2指向列表2
>>> l1=['xxx'] # 列表1被引用一次,列表1的引用计数变为1
>>> l2=['yyy'] # 列表2被引用一次,列表2的引用计数变为1
>>> l1.append(l2) # 把列表2追加到l1中作为第二个元素,列表2的引用计数变为2
>>> l2.append(l1) # 把列表1追加到l2中作为第二个元素,列表1的引用计数变为2
# l1与l2之间有相互引用
# l1 = ['xxx'的内存地址,列表2的内存地址]
# l2 = ['yyy'的内存地址,列表1的内存地址]
>>> l1
['xxx', ['yyy', [...]]]
>>> l2
['yyy', ['xxx', [...]]]
>>> l1[1][1][0]
'xxx'
循环引用
这种情况下我们将两个直接引用的过程直接切断,即del l1 and del l2 ,xxx和yyy的引用计数仍为1,这种情况下的引用计数回收机制就不会起作用
具体地:标记的过程其实就是,遍历所有的GC Roots对象(栈区中的所有内容或者线程都可以作为GC Roots对象),然后将所有GC Roots的对象可以直接或间接访问到的对象标记为存活的对象,其余的均为非存活对象,应该被清除。
清除:清除的过程将遍历堆中所有的对象,将没有标记的对象全部清除掉
分代回收
基于引用计数的回收机制,每次回收内存,都需要把所有对象的引用计数都遍历一遍,这是非常消耗时间的,于是引入了分代回收来提高回收效率,分代回收采用的是用“空间换时间”的策略。
分代回收的核心思想是:在经历多次扫描的情况下,都没有被回收的变量,GC机制就会认为,该变量是常用变量,GC对器扫描的频率就会降低
分代回收
分代指的是根据存活时间来为变量划分不同等级(也就是不同的代) 新定义的变量,放到新生代这个等级中,假设每隔1分钟扫描新生代一次,如果发现变量依然被引用,那么该对象的权重(权重本质就是个整数)加一,当变量的权重大于某个设定得值(假设为3),会将它移动到更高一级的青春代,青春代的gc扫描的频率低于新生代(扫描时间间隔更长),假设5分钟扫描青春代一次,这样每次gc需要扫描的变量的总个数就变少了,节省了扫描的总时间,接下来,青春代中的对象,也会以同样的方式被移动到老年代中。也就是等级(代)越高,被垃圾回收机制扫描的频率越低
例如一个变量刚刚从新生代移入青春代,该变量的绑定关系就解除了,该变量应该被回收,但青春代的扫描频率低于新生代,这就到导致了应该被回收的垃圾没有得到及时地清理。没有十全十美的方案:毫无疑问,如果没有分代回收,即引用计数机制一直不停地对所有变量进行全体扫描,可以更及时地清理掉垃圾占用的内存,但这种一直不停地对所有变量进行全体扫描的方式效率极低,所以我们只能将二者中和。综上垃圾回收机制是在清理垃圾&释放内存的大背景下,允许分代回收以极小部分垃圾不会被及时释放为代价,以此换取引用计数整体扫描频率的降低,从而提升其性能,这是一种以空间换时间的解决方案目录
进程
程序\进程的区别
程序:程序就是一堆在硬盘上的代码文件
进程:进程是一个抽象的概念,指的是程序的运行过程,进程是操作系统最核心的概念
进程调度
先来先服务调度算法
对长作业有利,对短作业无益
多作业优先度算法
对短作业有利,对长作业无益
时间片轮转法+多级反馈队列
时间片轮转法+多级反馈队列
进程的三状态
就绪
运行
阻塞
进程的三状态
进程三状态python简单了解
两对重要概念
同步和异步
描述的是任务的提交方式
同步:任务提交之后,原地等待任务的返回结果,等待的过程中不做任何事(干等)
程序层面上表现出来就是卡住了
异步:任务提交之后,不愿地等待任务的返回结果,直接去做其他事情
那么我提交的任务结果如何获取?
任务的返回结果有一个异步回调机制自动处理
阻塞和非阻塞
描述的是程序的运行状态
阻塞:阻塞态
非阻塞:就绪态\运行态
理想状态:我们应该让我们写的代码永远处于就绪态和运行态
最高效的一种组合状态:异步非阻塞
操作系统
操作系统的作用
隐藏丑陋复杂的硬件接口,提供良好的抽象接口
管理/调度进程,并且将多个进程对硬件的竞争变得有序
多道系统
想让单核cpu实现并发的效果
单核肯定不能实现并行,但是可以实现并发
直接假设单核就是一个核,干活的就是一个人,不考虑cpu里面的内核
串行:一个运行完毕后再运行下一个
多道图解
并发:看起来像是同时运行的,就可以称之为并发,本质还是一个个运行
并行:多个程序真正意义上的同时运行
空间上的复用
多个程序共用一套计算机硬件
时间上的复用
例子:洗衣服30s,做饭50s,烧水50s
单道需要110s(总时间),多道只需要任务最长时间的那个
切换节省时间,保存状态
切换分为两种情况
①当一个程序遇到IO操作的时候,操作系统会剥夺该程序cpu执行权限
作用:提高了cpu的利用率,并且也不影响程序的执行效率
②当一个程序长时间占用cpu的时候,操作系统也会剥夺该程序的cpu执行权限
作用:降低了程序的执行效率(原本时间+切换时间)
网友评论