GC - long_lived_pending is not decremented when a generation-2 object's ref count goes to 0
@pablogsal 已經在處理了。
開始於 2025年2月17日。
- 主要語言
- Python
- 星號
- 77.2k
- 分支
- 36k
- PR 合併指標
- PR 指標待擷取
描述
Bug report
Bug description:
Given the idea and documentation around the long_lived_pending / long_lived_total > 0.25 check, I would expect long_lived_pending to be the total number of objects that (1) have survived a generation-1 collection, and (2) are still live (i.e., ref count has not been decremented to 0).
From the behavior I'm seeing, I think only (1) is true. The example code below is contrived to promote many objects into generation-2 and then cause them to be deleted by their ref counts being decremented to 0. Hence there is no reason for Python to perform a generation-2 collection. Nevertheless, it does so repeatedly, collecting nothing each time. This seems sub-optimal, since these collections are expensive and are not doing anything.
import gc
import time
from typing import Any
class Temp:
pass
accumulating_list = []
def gc_callback(phase: str, info: dict[str, Any]) -> None:
generation = info['generation']
if generation == 2:
print(phase, info, len(gc.get_objects(2)))
if phase == "stop" and generation == 1:
# The GC that just ended will have promoted most of the Temps in
# accumulating_list into generation-2. Drop references to to them here,
# causing them to be immediately deleted.
accumulating_list.clear()
gc.callbacks.append(gc_callback)
gc.set_threshold(10, 2, 2)
for x in range(100000):
accumulating_list.append(Temp())
time.sleep(0.001)
Is it working as intended that long_lived_pending is not decremented when a corresponding object is deleted by its ref count dropping to 0? This would avoid generation-2 collections except where actually useful. It feels to me like this should happen, although perhaps it's infeasible or too expensive?
Note: Although this is a contrived example, we are seeing this in a real world largeish Python program. It's exacerbated by the default GC thresholds being set really low, which results in even short-lived objects (measured by time) being promoted quickly into generation-2.
CPython versions tested on:
3.11
Operating systems tested on:
macOS
貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
評估
這個 Issue 還沒有評估資料。