一、猴子补丁
第三方模块:下载 pip3
import json import ujson #在用之前先改好,不能多用,不然程序会被改的很乱 json.dumps=ujson.dumps json.loads=ujson.loads
import json import ujson # pip3 install ujson def monkey_patch(): json.__name__ = ujson.__name__ json.dumps = ujson.dumps json.loads = ujson.loads
二、GC垃圾回收机制
1、储备知识:
在定义变量时,变量名与变量值都是需要存储的,分别对应内存中的两块区域:堆区与栈区
直接引用指的是从栈区出发直接引用到的内存地址。
间接引用指的是从栈区出发引用到堆区后,再通过进一步引用才能到达的内存地址
l2 = [20, 30] # 列表本身被变量名l2直接引用,包含的元素被列表间接引用 x = 10 # 值10被变量名x直接引用 l1 = [x, l2] # 列表本身被变量名l1直接引用,包含的元素被列表间接引用
2、Python的GC模块主要运用了“引用计数”(reference counting)来跟踪和回收垃圾。在引用计数的基础上,还可以通过“标记-清除”(mark and sweep)解决容器对象可能产生的循环引用的问题,并且通过“分代回收”(generation collection)以空间换取时间的方式来进一步提高垃圾回收的效率。
1、引用计数:引用计数就是:变量值被变量名关联的次数
一个变量值的引用计数为0时,才会被当作垃圾回收
问题1:循环引用(交叉引用)=》内存泄漏
标记-清除
标记/清除算法的做法是当应用程序可用的内存空间被耗尽的时,就会停止整个程序,然后进行两项工作,第一项则是标记,第二项则是清除。 #1、标记 通俗地讲就是: 栈区相当于“根”,凡是从根出发可以访达(直接或间接引用)的,都称之为“有根之人”,有根之人当活,无根之人当死。 具体地:标记的过程其实就是,遍历所有的GC Roots对象(栈区中的所有内容或者线程都可以作为GC Roots对象),然后将所有GC Roots的对象可以直接或间接访问到的对象标记为存活的对象,其余的均为非存活对象,应该被清除。 #2、清除 清除的过程将遍历堆中所有的对象,将没有标记的对象全部清除掉。
问题2:效率问题
基于引用计数的回收机制,每次回收内存,都需要把所有对象的引用计数都遍历一遍,这是非常消耗时间的
分代回收
分代回收的核心思想是:在历经多次扫描的情况下,都没有被回收的变量,gc机制就会认为,该变量是常用变量,gc对其扫描的频率会降低。
分代指的是根据存活时间来为变量划分不同等级(也就是不同的代)
回收依然是使用引用计数作为回收的依据
---34---