变量
ipo
i input
p process
o output
变量: 定义世间万物变化的状态
变量的组成: 变量名(描述,接受变量值) 赋值符号 (赋值) 变量值(具体的值)
变量名的规范:
1.变量名必须要有描述意义
2.变量名由数字,字母,下划线组成,不能以数字开头
3.不能以关键字命名
定义变量的两种方式
1.下划线式
2.驼峰体
变量打印的三种属性
1.打印值
print(age)
2.打印内存地址
print(id(age))
3.打印数据类型
print(type(age))
常量
约定不变化的量
定义:变量名全大写
内存管理
定义变量并隐形,开辟一块内存空间
引用计数
针对变量值,被变量名引用的次数
垃圾回收机制
1.引用计数
1.对象被创建
>>>import sys
>>>a = 123
>>>sys.getrefcount(a)
3
>>>b = 456
>>>sys.getrefcount(b)
2
123是小整数池中,a又定义一次,getrefcount又调用一次,所以是三次
2.被引用或调用
>>> import os
>>> a = 456
>>> b = a
>>> c = b
>>> sys.getrefcount(a)
4
>>> sys.getrefcount(c)
4
>>> sys.getrefcount(b)
4
变量a,b,c指向数据456,而getrefcount也只算一次
- 循环引用会导致引用计数永不为0,空间永远不会被释放.
list1 = []
list2 = []
list1.append(list2)
list2.append(list1)
当一个变量值的引用计数为0时候,会触发垃圾回收机制,释放内存空间
id() 指出变量值在内存的内存地址
2.标记清除
标记清除(Mark-Sweep)算法是一种基于追踪回收(tracing GC)技术实现的垃圾回收算法.它分为两个阶段:第一阶段是标记阶段,GC会把所有的活动对象打上标记,第二阶段是把哪些没有标记的对象非活动对象进行回收.根对象就是全局变量,调用栈,寄存器.
标记清除算法作为Python的辅助垃圾收集技术,主要处理的是一些容器类对象,list,dict,tuple等.Python使用一个双向链表将这些容器对象组织起来.缺点:清除非活动对象前它必须顺序扫描整个内存,哪怕只剩下小部分活动对象也要扫描所有对象.
3.分代回收
分代回收是建立在标记清除技术基础之上的,是一种以空间换时间的操作方式.
Python将内存根据对象的存活时间划分为不同的集合,每个集合称为一个代,Python将内存分为了3代.分别为年轻代(第0代),中年代(第1代),老年代(第2代),他们对应的是3个链表,它们的垃圾回收频率随对象的存活时间的增大而减小.新创建的对象都会分配在年轻代,年轻代链表的总数达到上限时,Python垃圾回收机制就会被触发,把那些可以被回收的对象回收掉,而那些不会回收的对象就会被移到中年代,以此类推,老年代中的对象是存活时间最久的对象,甚至是存活于整个系统的生命周期内.
- 分代技术是一种典型的以空间换时间的技术,这也正是java里的关键技术。这种思想简单点说就是:对象存在时间越长,越可能不是垃圾,应该越少去收集。
- 这样的思想,可以减少标记-清除机制所带来的额外操作。分代就是将回收对象分成数个代,每个代就是一个链表(集合),代进行标记-清除的时间与代内对象
- 存活时间成正比例关系。
- 从上面代码可以看出python里一共有三代,每个代的threshold值表示该代最多容纳对象的个数。默认情况下,当0代超过700,或1,2代超过10,垃圾回收机制将触发。
- 0代触发将清理所有三代,1代触发会清理1,2代,2代触发后只会清理自己。
https://blog.csdn.net/qq_43029747/article/details/99846548
https://blog.csdn.net/wxfghy/article/details/80901488
小整数池(池中数字不会触发垃圾回收机制)
python启动时,会自动定义[-5,256]之间的整数变量,内存空间写死
(pycharm会扩大整数池,短平快)
gil全局解释器锁