6.7 python内存相关--小数据池
变量的赋值
类型
说明
定义
变量的赋值即创建一个内存对象的引用,即对象名指向内存中某个特定的对象;
变量在内存的变现形式
变量存在于进程创建的名称空间中,采用映射关系表存放,变量名的值为一段内存地址,
该内存地址指向该变量引用的对象;
变量的赋值的底层原理
step1: 创建该内存对象;
step2: 在特定的名称空间中创建特定的变量名;
step3: 让变量名指向创建的内存对象;
引用计数器
类型
说明
定义
python中一切皆对象,引用计数器则是解释器用于维护一个内存对象被引用的次数;
一个对象被某个变量指向或被某段代码调用即创建了该对象的引用;
变量初始化赋值:如 A=300
创建内存对象300,并采用变量名A指向内存对象300;对象300引用计数加一;
变量A在名称空间中存放的是对象300的内存地址
变量重新赋值:如,A=300 ;A=100
初始时:变量A指向内存对象300;对象300的引用计数器加一;
重新赋值:变量A指向新的内存对象100,原内存对象300的不在被变量A引用,
对象300的引用计数器减一,而内存对象100的引用计数加一;
变量赋值给变量:如 A=300;B=A
初始时:变量A赋值300,创建变量A指向对象300的引用,并让对象300的引用计数加一;
变量赋值给变量:即将对象A的值---对象300的内存地址赋值给变量B;
变量B也指向了内存对象300,系统将内存对象300的引用计数器加一;
查看某个对象的引用计数方法
以对象88为例:
>>>A=88
>>>import sys
>>>sys.getrefcount(88)
内存回收机制
全局级垃圾回收机制
python不同于其它编程语言,python程序在执行过程中所产生的在内存中的数据,其在程序执行完成时会自动被解释器进行回收,释放内存空间;而其它编程语言则需要程序员手动的去进行内存的垃圾回收;
内存垃圾回收触发条件
python一切皆对象,一个对象的引用计数器在变为0时,解释器会在其底层自动化删除该对象回收该对象所占用的内存空间;解释器的此种自动回收机制并不会在对象的引用计数器为0时立即进行垃圾回收,而是会根据其繁忙程度,在解释器较空闲时自动底层完成内存资源的回收,无序程序员的干预;
主动垃圾回收方法
del var //删除引用对象的变量,让对象的引用计数器变为0;
小数据池
编程语言
是否存在小数据池
python
仅仅针对数字,字符串存在小数据池
其他所有的数据类型均不存在小数据池
数字、字符串:特定条件的数字和字符串的赋值给不同的变量,
此两个变量指向的是同一个对象的引用
其它数据类型:两个变量赋的值相同,
此两个变量仍然引用的是不通的内存对象;
其他
不存在小数据池
给变量赋值时,若给两个变量赋的值相等,
此两个变量指向的是不同的内存对象;
全局小数据池---整个程序代码
数据类型
小数据池条件
数字
范围:[-5,256];
字符串
python2:
普通字符串:仅仅只含有英文字母(大小写均可)、数字、下划线构成的字符串,无论多长均会进行缓存;
单个字符重复n次:'char'*n生成的字符串,char重复20次以内(含20次),均会进行缓存;
python3:
普通字符串:仅仅只含有英文字母(大小写均可)、数字、下划线构成的字符串,无论多长均会进行缓存;
单个字符重复n次:'char'*n生成的字符串,char无论重复多少次,均会进行缓存;
无小数据池优化
总结:
针对数字而言: 两个对象赋的值在[-5,256]范围内,且值相同,则此两个变量引用的是同一个变量;
针对字符串而言:
普通字符串: 只要字符串中仅仅由大小写英文字符、数字、下划线构成,无论多长,只要值相等,两个变量引用的是同一个对象
注意此规则仅仅适用于采用:var_name='str'定义的普通字符串;采用var='char'*n构建的字符串不符合此规则
单个字符重复: 注意此规则,仅仅使用于:var_name='char'*n构建的普通字符串;
同时:char必须为普通字符(大小写英文字符或数字或下划线)
python2:n的范围在[1,20]构成的字符串,只要两个对象的值相等,两个变量引用同一个对象;
而超过20次,即使值相等,引用的仍然不是同一个对象;
python3:n无论多大,只要值相等,两个对象引用的都是同一个对象;
代码块级别小数据池
程序的结构:
程序 \
程序: 由一个执行入口程序文件+多个完成特定功能的模块文件构成,组合实现特定的功能的程序;
模块: 模块由一个一个语句去构成;
语句: 用于定义做某事,由表达式构成;
表达式:定义某事,由对象构成;
对象: python中一切皆对象;
代码块:
Python程序由代码块构成,代码块作为程序的一个最小基本单位来执行。一个模块文件、一个函数体、一个类、交互式命令中的单行代码都叫做一个代码块。 即python的一个语句即为一个代码块;
模块、函数、类、单行代码,等一个python语句包含其所有的子代码构成一个代码块;
代码块级别的小数据池:
同一个代码块中的不可变对象,只要值是相等的就不会重复创建新的对象。
总结说明
全局级小数据池
出于对性能的考虑,Python内部做了很多的优化工作,对于整数对象,Python把一些频繁使用的整数对象缓存起来,保存到一个叫small_ints的链表中,在Python的整个生命周期内,任何需要引用这些整数对象的地方,都不再重新创建新的对象,而是直接引用缓存中的对象。Python把这些可能频繁使用的整数对象规定在范围[-5, 256]之间的小对象放在small_ints中,但凡是需要用些小整数时,就从这里面取,不再去临时创建新的对象。同理对于字符串而言,常用的字符串都是不含有特殊字符的字符串,同样的,python会把这些频繁使用的字符串缓存起来,下次再同样赋值给一个变量时,不会再去开辟内存空间存储这些字符串,而是直接引用原来的内存中的字符串;
代码块级的小数据池
同样为了性能优化,节省内存空间;Python内部为了将性能进一步的提高,凡是在一个代码块中的不可变对象,只有是值相同的对象,就不会重复创建,而是直接引用已经存在的对象;
文件小数据次
在一个py文件中,只要内容一样,内存就一样;