Py学习  »  Python

系统。refcount()返回的值比预期的python3大得多

Rohit Agharkar • 3 年前 • 1306 次点击  

我正在用python学习GIL,并尝试运行sys。refcount()和接收的值为148。这可能是一个非常简单的问题,任何帮助都将不胜感激。

为什么值是148而不是2?

import sys

c = 1
print(sys.getrefcount(c))

>>> 148
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/129862
文章 [ 2 ]  |  最新文章 3 年前
Alexander
Reply   •   1 楼
Alexander    4 年前

int 这很特别。

它的值非常多(双关语)而且很小,这是远对象开销方面最糟糕的情况(它浪费时间进行分配,GCs变得更慢,因为它们有更多堆对象要扫描,并且浪费时间进行引用计数和取消分配)。通常情况下,语言运行时会花费大量时间来优化特殊情况,比如 智力 , bool

根据Python的具体实现,有可能 智力 对象表示为:

  1. 常规的、普通的堆分配对象(即,没有特殊的优化)。
  2. 作为常规的堆分配对象,但使用一个共享对象池来表示所有最常见的值。(例如,每一次 1 是同一个对象,被引用 到处都是 1. (已使用)
  3. 或者作为一个 tagged pointer ,这完全不涉及堆分配(对于适当小的整数值)。

在案例2或3中,如果它是“普通”对象,它的引用计数将不是您可能期望的。

Tim Peters
Reply   •   2 楼
Tim Peters    4 年前

你的Python代码不是唯一运行的东西。Python标准库的大部分内容都是编写的 在里面 Python,这取决于您使用的shell,这可能会导致在第一次键入之前导入相当多的模块。在CPython 3.10.0的空闲状态下:

>>> import sys
>>> len(sys.modules)
159

因此,只要到达提示(!)模块“在封面下”。

“小”整数对象由CPython实现跨用途共享。所有这些模块中的每个3实例都会增加3的refcount。以下是其他一些:

>>> for i in range(-10, 11):
...     print(i, sys.getrefcount(i))
-10 3
-9 3
-8 3
-7 3
-6 3
-5 9
-4 5
-3 12
-2 25
-1 190
0 914
1 804
2 363
3 144
4 202
5 83
6 83
7 38
8 128
9 54
10 64

所以3“相当受欢迎”,但0是容易的赢家。但是没有其他东西在使用,例如-10或-9。

但请注意 知道 这对你来说没有实际价值。Python是否以及何时共享不可变对象由实现定义,并且可以(而且确实如此!)在不同版本之间进行更改。