Why is a task created with asyncio.create_task()
in the below not garbage collected?
import asyncio
import gc
c = 0
async def run():
global c
try:
while True:
await asyncio.sleep(1)
c += 1
except Exception as e:
print(e)
async def main():
task = asyncio.create_task(run())
del task
while True:
await asyncio.sleep(0.2)
print(c)
gc.collect()
asyncio.run(main())
Expected:
0
0
0
asyncio.CancelledError
Actual:
0
0
0
0
0
1
1
1
1
1
..
101
101
101
101
101
102
...
2
task = asyncio.create_task(run()) del task
The local variable task
was not the only reference to the task. asyncio.create_task
has created one or more references to the task which are still used by asyncio
, so it is not garbage-collected.
You can see which objects hold references to the task by using gc.get_referrers
:
task = asyncio.create_task(run())
print(gc.get_referrers(task))
del task
Output:
[<TaskStepMethWrapper object at 0x7f04ff32ece0>]
which is one of these.