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

只需使用以下代码进行测试:

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