python 内存管理,深浅拷贝
大小整数池子
小整数池
数据类型之可变/不可变。
可变的数据类型 list,dict,set 可变,就是里面的数据类型变了,指向内存没变
不可变的数据类型 str, 数值,tup元祖 不可变,如果改变了值,指向内存会发生改变,称不可变。
小整数池子
-5~256 只要是在这个区间范围内的数值是python已经在后台生成好的,
如果定义变量的值在此区间内会直接饮用内存地址指向变量。
大整数池子,intern机制
针对字符串存储
注意: 只存储包含标准字符(数字,字母,下划线)的字符串
包含特殊字符的字符串不会被添加到大整数池中。
当定义一个标准的字符串之后会自动将字符串放入大整数池子中,后面再次进行字符串定义时,python会在池子中寻找是否已经被定义,没被定义则会从新开辟内存进行字符串定义
如果找到的话,就简单的对值进行引用。
简单来说intern优点就是,在创建新的字符串的时,会现在里面寻找是否已经有存在的值相同的对象,如果有,直接拿来用,避免重复创建和销毁内存,提升效率。
深浅拷贝
浅拷贝
浅拷贝不用额外的库
浅拷贝只会拷贝最外层的,里面如果有嵌套的,嵌套的数据内存指向是不会变的,所以当浅拷贝一个列表,原先的列表发生变动,浅拷贝生成的列表也会随之改变,来看实例
# 浅拷贝
list1 = [1, 2, 3]
list2 = [1,2,list1]
list3 = list2.copy()
list1.append(4)
print(list3)
"""
浅拷贝只会拷贝最外层的,里面如果有嵌套的,嵌套的数据内存指向是不会变得
例子:
上面copy了list2,list3跟list2指向的内存地址发生了变化,但是里面嵌套
的list1 内存地址并没有发生变化,所以修改了list1的值,list3也会发生变化
深拷贝
拷贝过来的数据都会开辟新的内存空间,不会跟以前的占用一个内存空间。
同时深拷贝需要使用到copy模块的deepcopy方法
# 深拷贝
例子:
浅拷贝
list1 = [1, 2, 3]
list2 = [1, 2, list1]
list3 = list2.copy()
list4 = copy.deepcopy(list2)
list1.append(5)
print(list4)
"""
深拷贝,拷贝过来的数据都会开辟新的内存空间,不会跟以前的占用一个内存空间
python垃圾回收机制
python的垃圾回收机制一句话形容就是,
引用计算机制为主,标记清除和分代回收两种机制为辅的策略。
因为引用计数会存在一个内存泄漏的问题,比如说变量之间的相互引用,会产生循环引用。
引用计数的机制是,只要没有对象引用内存中的某个变量,该变量就会被垃圾回收
引用计数举例
例子 a=123 ,b =123
这时候123 开辟出来的内存空间就被引用了两次,计数为2,这就是引用计数
如果b的值被改变,这时候对于123的引用计数为1,如果a的值也被改变,这时候 123 就会被回收掉
优点
简单实时,一旦没有引用,内存就直接释放掉,不用像其他机制等待特定的实际,实时性还带来一个好处,处理回收内存的时间分摊到了平时
缺点
维护引用计数消耗资源,且会造成循环引用导致无法回收,引发内存泄漏
标记清除
标记-清除 机制,首先标记对象(垃圾检测,)然后清除垃圾(垃圾回收)
检测该对象有没有变量引用它,没有就标记为垃圾
分代回收
1,分代技术是一种典型的以空间换时间的技术,这也是java里的关键技术,这种思想简言之就是:对象存在时间越长,月可能不是垃圾,应该减少去手机
2,这样的思想,可以减少标记-清除机制带来的额外操作。分代就是将回收对象分成数个带,没个贷就是一个链表(集合)带进行标记-清除的时间与代内对象
3,存活时间成正比例关系
4,从上面代码可以看出python里一共有三代,每个代的threshold值表示代表最多容纳对象的个数,默认情况下,当0代超过700,或1,2代超过10,垃圾回收机制就会被触发
5,0代触发将清理所有三代, 1代触发会清理1,2代,2代触发后只会清理自己。