lru是一种缓存淘汰算法
(least recently used)即最近最少使用淘汰算法
不用lru_cache
使用lru_cache
lru_cache的定义如下,
第一个参数maxsize控制最大缓存数量,
第二个参数为True则严格检查被装饰函数的参数类型Python采用自动内存管理,即Python会自动进行垃圾回收,不需要像C、C++语言一样需要程序员手动释放内存,手动释放可以做到实时性,但是存在内存泄露、空指针等风险。
Python自动垃圾回收也有自己的优点和缺点:优点:
缺点:
Python的垃圾回收机制采用 以引用计数法为主,分代回收为辅 的策略。
先聊引用计数法,Python中每个对象都有一个核心的结构体,如下
一个对象被创建时,引用计数值为1,当一个变量引用一个对象时,该对象的引用计数ob_refcnt就加一,当一个变量不再引用一个对象时,该对象的引用计数ob_refcnt就减一,Python判断是否回收一个对象,会将该对象的引用计数值ob_refcnt减一判断结果是否等于0,如果等于0就回收,如果不等于0就不回收,如下:
一个对象在以下三种情况下引用计数会增加:
一个对象在以下三种情况引用计数会减少:
验证案例:
运行结果:
事实上,关于垃圾回收的测试,最好在终端环境下测试,比如整数257,它在PyCharm中用下面的测试代码打印出来的结果是4,而如果在终端环境下打印出来的结果是2。这是因为终端代表的是原始的Python环境,而PyCharm等IDE做了一些特殊处理,在Python原始环境中,整数缓存的范围是在 [-5, 256] 的双闭合区间内,而PyCharm做了特殊处理之后,PyCharm整数缓存的范围变成了 [-5, 无穷大],但我们必须以终端的测试结果为主,因为它代表的是原始的Python环境,并且代码最终也都是要发布到终端运行的。
好,那么回到终端,我们来看两种特殊情况
前面学习过了,整数缓存的范围是在 [-5, 256] 之间,这些整数对象在程序加载完全就已经驻留在内存之中,并且直到程序结束退出才会释放占有的内存,测试案例如下:
如果字符串的内容只由字母、数字、下划线构成,那么它只会创建一个对象驻留在内存中,否则,每创建一次都是一个新的对象。
引用计数法有缺陷,它无法解决循环引用问题,即A对象引用了B对象,B对象又引用了A对象,这种情况下,A、B两个对象都无法通过引用计数法来进行回收,有一种解决方法是程序运行结束退出时进行回收,代码如下:
前面讲过,Python垃圾回收机制的策略是 以引用计数法为主,以分代回收为辅 。分代回收就是为了解决循环引用问题的。
Python采用分代来管理对象的生命周期:第0代、第1代、第2代,当一个对象被创建时,会被分配到第一代,默认情况下,当第0代的对象达到700个时,就会对处于第0代的对象进行检测和回收,将存在循环引用的对象释放内存,经过垃圾回收后,第0代中存活的对象会被分配为第1代,同样,当第1代的对象个数达到10个时,也会对第1代的对象进行检测和回收,将存在循环引用的对象释放内存,经过垃圾回收后,第1代中存活的对象会被分配为第2代,同样,当第二代的对象个数达到10个时,也会对第2代的对象进行检测和回收,将存在循环引用的对象释放内存。Python就是通过这样一种策略来解决对象之间的循环引用问题的。
测试案例:
运行结果:
如上面的运行结果,当第一代中对象的个数达到699个即将突破临界值700时(在打印699之前就已经回收了,所以看不到698和699)进行了垃圾回收,回收掉了循环引用的对象。
第一代、第二代、第三代分代回收都是有临界值的,这个临界值可以通过调用 gcget_threshold 方法查看,如下:
当然,如果对默认临界值不满意,也可以调用 gcset_threshold 方法来自定义临界值,如下:
最后,简单列出两个gc的其它方法,了解一下,但禁止在程序代码中使用
以上就是对Python垃圾回收的简单介绍,当然,深入研究肯定不止这些内容,目前,了解到这个程度也足够了。
关键词:正则表达式 | 缓存 | 性能优化
Python 3 的 re 库中,对正则表达式的编译函数 recompile() 调用了私有函数 re_compile() ,但更根本上编译的计算是由 sre_compilecompile() 完成的,而 re_compile() 中对编译好的表达式进行了缓存,使用 _MAXCACHE 将缓存大小硬编码为512。以下是 re_compile() 的源码,摘自: >想要查看一个db下有多少key,在Redis-cli中输入 keys 即可
如果想删除某个key 可以使用del 命令 例如: del key delkey(你要删除的key的名称)
那么Python如何来查看呢?
[cpp] view plain copy
# coding=utf-8
'''
Created on 2015-9-8
@author: kwsy
'''
import redis
pool=redisConnectionPool(host='1921681126',port=6379,db=0)
r = redisStrictRedis(connection_pool=pool)
keys = rkeys()
print type(keys)
print keys
keys的type是 list ,所有的key将存入这个list作为结果返回
如果想返回特定形式的key,可以在keys()函数中添加参数,例如keys = rkeys("finger") 那么将只返回以finger开头的key
key的删除也非常简单
[cpp] view plain copy
# coding=utf-8
'''
Created on 2015-9-8
@author: kwsy
'''
import redis
pool=redisConnectionPool(host='1921681126',port=6379,db=0)
r = redisStrictRedis(connection_pool=pool)
rdelete("del1","del2")
我这里是同时删掉两个key
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)