① python 缓存
详解: https://pythonav.com/wiki/detail/6/88/
一.
1.int 类型的缓存
[-5, 256]的整型,只要Python解释器一运行,这些数值就加载到了内存
2.free_list:float、list、touple、dict等都是这种方式
当一个对象引用计数为0时,按理说就应该被垃圾回收了,但是Python不是这么做的,而是将对象放入到free_list链表里面。这样,以后再去创建该对象时,不会重新开辟内存,而是直接使用free_list里面的
② python有缓存模块吗
从Python 3.2开始,可以使用functools库中的装饰器@lru_cache。这是最近使用过的缓存,所以其中的项目没有到期时间,但作为快速入侵,它非常有用。
from functools import lru_cache
@lru_cache(maxsize=256)def f(x):
return x*xfor x in range(20):
print f(x)for x in range(20):
print f(x)
③ Python内存驻留机制
字符串驻留机制在许多面向对象编程语言中都支持,比如Java、python、Ruby、PHP等,它是一种数据缓存机制,对不可变数据类型使用同一个内存地址,有效的节省了空间,本文主要介绍Python的内存驻留机制。
字符串驻留就是每个字符串只有一个副本,多个对象共享该副本,驻留只针对不可变数据类型,比如字符串,布尔值,数字等。在这些固定数据类型处理中,使用驻留可以有效节省时间和空间,当然在驻留池中创建或者插入新的内容会消耗一定的时间。
下面举例介绍python中的驻留机制。
在Python对象及内存管理机制一文中介绍了python的参数传递以及以及内存管理机制,来看下面一段代码:
知道结果是什么吗?下面是执行结果:
l1和l2内容相同,却指向了不同的内存地址,l2和l3之间使用等号赋值,所以指向了同一个对象。因为列表是可变对象,每创建一个列表,都会重新分配内存,列表对象是没有“内存驻留”机制的。下面来看不可变数据类型的驻留机制。
在 Jupyter或者控制台交互环境 中执行下面代码:
执行结果:
可以发现a1和b1指向了不同的地址,a2和b2指向了相同的地址,这是为什么呢?
因为启动时,Python 将一个 -5~256 之间整数列表预加载(缓存)到内存中,我们在这个范围内创建一个整数对象时,python会自动引用缓存的对象,不会创建新的整数对象。
浮点型不支持:
如果上面的代码在非交互环境,也就是将代码作为python脚本运行的结果是什么呢?(运行环境为python3.7)
全为True,没有明确的限定临界值,都进行了驻留操作。这是因为使用不同的环境时,代码的优化方式不同。
在 Jupyter或者控制台交互环境 中:
满足标识符命名规范的字符:
结果:
乘法获取字符串(运行环境为python3.7)
结果:
在非交互环境中:
注意: 字符串是在编译时进行驻留 ,也就是说,如果字符串的值不能在编译时进行计算,将不会驻留。比如下面的例子:
在交互环境执行结果如下:
都指向不同的内存。
python 3.7 非交互环境执行结果:
发现d和e指向不同的内存,因为d和e不是在编译时计算的,而是在运行时计算的。前面的 a = 'aa'*50 是在编译时计算的。
除了上面介绍的python默认的驻留外,可以使用sys模块中的intern()函数来指定驻留内容
结果:
使用intern()后,都指向了相同的地址。
本文主要介绍了python的内存驻留,内存驻留是python优化的一种策略,注意不同运行环境下优化策略不一样,不同的python版本也不相同。注意字符串是在编译时进行驻留。
--THE END--
④ python的内存管理机制
论坛
活动
招聘
专题
打开CSDN APP
Copyright © 1999-2020, CSDN.NET, All Rights Reserved
登录
XCCS_澍
关注
Python 的内存管理机制及调优手段? 原创
2018-08-05 06:50:53
XCCS_澍
码龄7年
关注
内存管理机制:引用计数、垃圾回收、内存池。
一、引用计数:
引用计数是一种非常高效的内存管理手段, 当一个 Python 对象被引用时其引用计数增加 1, 当其不再被一个变量引用时则计数减 1. 当引用计数等于 0 时对象被删除。
二、垃圾回收 :
1. 引用计数
引用计数也是一种垃圾收集机制,而且也是一种最直观,最简单的垃圾收集技术。当 Python 的某个对象的引用计数降为 0 时,说明没有任何引用指向该对象,该对象就成为要被回收的垃圾了。比如某个新建对象,它被分配给某个引用,对象的引用计数变为 1。如果引用被删除,对象的引用计数为 0,那么该对象就可以被垃圾回收。不过如果出现循环引用的话,引用计数机制就不再起有效的作用了
2. 标记清除
如果两个对象的引用计数都为 1,但是仅仅存在他们之间的循环引用,那么这两个对象都是需要被回收的,也就是说,它们的引用计数虽然表现为非 0,但实际上有效的引用计数为 0。所以先将循环引用摘掉,就会得出这两个对象的有效计数。
3. 分代回收
从前面“标记-清除”这样的垃圾收集机制来看,这种垃圾收集机制所带来的额外操作实际上与系统中总的内存块的数量是相关的,当需要回收的内存块越多时,垃圾检测带来的额外操作就越多,而垃圾回收带来的额外操作就越少;反之,当需回收的内存块越少时,垃圾检测就将比垃圾回收带来更少的额外操作。
⑤ python threading.local 有缓存吗
#coding=utf-8
import threading
# 创建全局ThreadLocal对象:
localVal = threading.local()
localVal.val = "Main-Thread"
def process_student():
print '%s (in %s)' % (localVal.val, threading.current_thread().name)
def process_thread(name):
#赋值
localVal.val = name
process_student()
t1 = threading.Thread(target= process_thread, args=('One',), name='Thread-A')
t2 = threading.Thread(target= process_thread, args=('Two',), name='Thread-B')
t1.start()
t2.start()
t1.join()
t2.join()
print localVal.val