Python VM是否缓存了不能自动释放的整型对象?
Does Python VM cache the integer objects which cannot be released automatically?
我有一个脚本如下:
a = 999999999999999999999999999999
b = 999999999999999999999999999999
print(a is b)
输出为:
[root@centos7-sim04 python]# python test2.py
True
另一方面,使用命令行的相同代码:
>>> a = 999999999999999999999999999999
>>> b = 999999999999999999999999999999
>>> print(a is b)
False
输出为False
。
- 这两种方式有什么区别?
- 当python脚本运行时,PythonVM如何管理整型对象?
- 我看到从-5到256的数字是在VM启动时由VM自动生成的,VM也会分配空的int块(chain struct)以避免为大数存储频繁分配内存。
- 内存不足时pythonVM会自动释放这些块吗?据我了解,Python只是保留这些块以避免频繁分配内存,这样它们就不会在分配后自动释放?
只需使用以下代码进行测试:
for i in range(1, 100000000):
pass
print("OK")
gc.collect()
time.sleep(20)
print("slept")
for i in range(1, 100000000)
pass
内存为:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
17351 root 20 0 3312060 3.039g 2096 S 11.3 82.4 0:03.53 python
这是 vmstat
的结果:
[root@centos7-sim04 ~]# vmstat 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 3376524 40 330084 0 0 2 5 25 41 0 0 100 0 0
1 0 0 185644 40 330084 0 0 0 0 714 28 14 3 82 1 0
0 0 0 967420 40 330084 0 0 0 0 292 15 7 0 93 0 0
0 0 0 967296 40 330084 0 0 0 0 20 23 0 0 100 0 0
0 0 0 967296 40 330084 0 0 0 0 15 17 0 0 100 0 0
0 0 0 967312 40 330068 0 0 0 1 27 39 0 0 100 0 0
1 0 0 185288 40 330068 0 0 0 2 701 55 17 0 83 0 0
0 0 0 3375780 40 330068 0 0 0 0 202 75 3 1 96 0 0
- 好像内存一直没有释放。这样对吗?
- 如果内存不够用,想释放整型对象,怎么办?
非常感谢。
===============================更新============= ==================
range() in Python2 returns 保留所有项目的完整列表和 Python2 returns 生成器中的 xrange()。
xrange() 是 Python3.
中的 range() 函数
这是 python 中生成器的 link 以及 PEP link,
https://wiki.python.org/moin/Generators & https://www.python.org/dev/peps/pep-0255/
关于你的第一个问题,它基本上与简化表达式的窥孔优化器有关。即对所有相等的值使用一个整数对象。它还使用这种方法来驻留字符串。
您在交互式 shell 中看不到这种行为的原因是每个命令都单独执行并给出相应的结果,而在文件或函数(甚至在终端中)中所有命令立即解释。这是一个例子:
In [1]: def func():
...: a = 9999999999999
...: b = 9999999999999
...: return a is b
...:
In [2]: func()
Out[2]: True
In [3]: a = 9999999999999
In [4]: b = 9999999999999
In [5]: a is b
Out[5]: False
关于你的第二个问题,其实这里有很多误解。首先,python 中 VM 的职责是执行与每个字节码对应的机器代码,而管理整数并实际解析代码并编译为字节码是解释器和编译器的任务。正如评论中提到的那样,range()
在 python 2 returns 中是一个列表,而在 python 3 中它是一个保留开始、结束和步骤的智能对象,并且是一个类似生成器的对象,按需生成项目。
还有关于 gc.collect
的功能,如 documentation 中所述,当您不向它传递参数时,gc.collect
运行 一个完整的集合,以及:
The free lists maintained for a number of built-in types are cleared
whenever a full collection or collection of the highest generation (2)
is run. Not all items in some free lists may be freed due to the
particular implementation, in particular float
我有一个脚本如下:
a = 999999999999999999999999999999
b = 999999999999999999999999999999
print(a is b)
输出为:
[root@centos7-sim04 python]# python test2.py
True
另一方面,使用命令行的相同代码:
>>> a = 999999999999999999999999999999
>>> b = 999999999999999999999999999999
>>> print(a is b)
False
输出为False
。
- 这两种方式有什么区别?
- 当python脚本运行时,PythonVM如何管理整型对象?
- 我看到从-5到256的数字是在VM启动时由VM自动生成的,VM也会分配空的int块(chain struct)以避免为大数存储频繁分配内存。
- 内存不足时pythonVM会自动释放这些块吗?据我了解,Python只是保留这些块以避免频繁分配内存,这样它们就不会在分配后自动释放?
只需使用以下代码进行测试:
for i in range(1, 100000000):
pass
print("OK")
gc.collect()
time.sleep(20)
print("slept")
for i in range(1, 100000000)
pass
内存为:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
17351 root 20 0 3312060 3.039g 2096 S 11.3 82.4 0:03.53 python
这是 vmstat
的结果:
[root@centos7-sim04 ~]# vmstat 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 3376524 40 330084 0 0 2 5 25 41 0 0 100 0 0
1 0 0 185644 40 330084 0 0 0 0 714 28 14 3 82 1 0
0 0 0 967420 40 330084 0 0 0 0 292 15 7 0 93 0 0
0 0 0 967296 40 330084 0 0 0 0 20 23 0 0 100 0 0
0 0 0 967296 40 330084 0 0 0 0 15 17 0 0 100 0 0
0 0 0 967312 40 330068 0 0 0 1 27 39 0 0 100 0 0
1 0 0 185288 40 330068 0 0 0 2 701 55 17 0 83 0 0
0 0 0 3375780 40 330068 0 0 0 0 202 75 3 1 96 0 0
- 好像内存一直没有释放。这样对吗?
- 如果内存不够用,想释放整型对象,怎么办?
非常感谢。
===============================更新============= ==================
range() in Python2 returns 保留所有项目的完整列表和 Python2 returns 生成器中的 xrange()。 xrange() 是 Python3.
中的 range() 函数这是 python 中生成器的 link 以及 PEP link,
https://wiki.python.org/moin/Generators & https://www.python.org/dev/peps/pep-0255/
关于你的第一个问题,它基本上与简化表达式的窥孔优化器有关。即对所有相等的值使用一个整数对象。它还使用这种方法来驻留字符串。
您在交互式 shell 中看不到这种行为的原因是每个命令都单独执行并给出相应的结果,而在文件或函数(甚至在终端中)中所有命令立即解释。这是一个例子:
In [1]: def func():
...: a = 9999999999999
...: b = 9999999999999
...: return a is b
...:
In [2]: func()
Out[2]: True
In [3]: a = 9999999999999
In [4]: b = 9999999999999
In [5]: a is b
Out[5]: False
关于你的第二个问题,其实这里有很多误解。首先,python 中 VM 的职责是执行与每个字节码对应的机器代码,而管理整数并实际解析代码并编译为字节码是解释器和编译器的任务。正如评论中提到的那样,range()
在 python 2 returns 中是一个列表,而在 python 3 中它是一个保留开始、结束和步骤的智能对象,并且是一个类似生成器的对象,按需生成项目。
还有关于 gc.collect
的功能,如 documentation 中所述,当您不向它传递参数时,gc.collect
运行 一个完整的集合,以及:
The free lists maintained for a number of built-in types are cleared whenever a full collection or collection of the highest generation (2) is run. Not all items in some free lists may be freed due to the particular implementation, in particular float