Python内存管理

Python内存管理

变量存哪了?

1
2
vim p1.py
x = 10

当我们在p1.py中定义一个变量x=10,那么计算机把这个变量值10存放在哪里了呢?
回顾计算机的三大核心组件为:CPU、内存和硬盘。一定不是CPU,那是存放在内存还是硬盘中了呢?
再回顾变量运行的三个过程,如果我们没有使用Python解释器运行p1.py这个文件,那么x=10很明显只是很普通的四个字符x、=、1、0。而只有Python解释器运行了这个文件,那字符进入了内存,才会有变量这个概念。也就是说变量是存放在内存当中的。

变量存放在内存中这句话太宽泛了,我们把它具体化。现在想象我们在学校(电脑内存)里上课,学校每开一个班,学校都会开辟一个教室给这个班级上课用(存放变量值10),而班级的门牌号则是(变量名x)。也就是说,对于电脑内存这个大内存,每定义一个变量就会在这个大内存中开辟一个小空间,小空间内存放变量值10,然后内存给这个小空间一个变量名x(门牌号),x指向10。

Python垃圾回收机制

对于p1.py,如果我们再加上一段代码x=11,大内存会开辟另一个小空间存储变量值11,把变量值绑定另一个门牌号x,但是由于之前有x,所以大内存会解除x与10的连接,让x与11连接。这个时候10由于没有了门牌号,所以成为了Python眼中的垃圾,Python就会处理这个垃圾,释放10的内存占用,这就是Python的垃圾回收机制。而其他语言需要手动把10的内存占用释放掉。

引用计数

从上述的解释我们可以知道只要某个变量值绑定着门牌号,就不是垃圾,反之变量值没有绑定着门牌号,这个变量值就是垃圾,Python就会自动清理这个垃圾。这里我们对于这个门牌号给定一个专业的解释,在Python中这个门牌号被称作引用计数。

1
2
3
4
x = 257  # 257 引用计数加1为1
y = x # 257 引用计数加1为2
x = 258 # 257 引用计数减1为1;258引用计数加1为1
del y # 257 引用计数减1为0,触发Python垃圾回收机制,Python清理257的内存占用

上述代码就是一个引用计数加减的过程。

小整数池

对于引用计数,需要注意的是:Python实现int的时候有个小整数池。为了避免因创建相同的值而重复申请内存空间所带来的效率问题,Python解释器会在启动时创建出小整数池,范围是[-5,256],该范围内的小整数对象是全局解释器范围内被重复使用,永远不会被回收。

在PyCharm中运行Python程序时,PyCharm出于对性能的考虑,会扩大小整数池的范围,其他的字符串等不可变类型也都包含在内一便采用相同的方式处理了,我们只需要记住这是一种优化机制,至于范围到底多大,无需细究。

1
2
3
4
5
6
x = 10   # 10引用计数加1为1
y = x # 10引用计数加1为2
z = 10 # 10引用计数加1为3
x = 11 # 10引用计数减1为2;11引用计数加1为1
del y # 10引用计数减1为1
del z # 10引用计数减1为0,但不触发Python垃圾回收机制,因为10数据Python小整数池内的数,会在Python解释器关闭前一直存在
---------------- The End ----------------
0%