Python aiohttp ClientSession 请求内存泄漏?

Gra*_*ant 5 python python-asyncio aiohttp

我相信在使用 aiohttp ClientSession 请求时,我在长期存在的应用程序中发现了内存泄漏。如果按顺序等待每个发出请求的协程,那么一切似乎都很好。然而,并发运行时似乎存在请求上下文管理器对象的泄漏。

请考虑以下示例代码:

import logging
import tracemalloc
import asyncio
import aiohttp


async def log_allocations_coro():

    while True:
        await asyncio.sleep(120)
        snapshot = tracemalloc.take_snapshot()
        top_stats = snapshot.statistics('lineno')
        str_list = [str(x) for x in top_stats[:5]]
        logging.info("\n".join(str_list))


async def do_request():

    try:
        async with session.request("GET", "http://192.168.1.1") as response:
            text = await response.text()
    except:
        logging.exception("Request failed")


async def main():

    tracemalloc.start()
    asyncio.ensure_future(log_allocations_coro())
    
    timeout = aiohttp.ClientTimeout(total=1)
    global session
    session = aiohttp.ClientSession(timeout=timeout)

    while True:

        tasks = [ do_request(), do_request() ]
        await asyncio.gather(*tasks)
        await asyncio.sleep(2)


if __name__ == '__main__':

    logging.basicConfig(format='%(asctime)s %(message)s', level=logging.INFO)
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
Run Code Online (Sandbox Code Playgroud)

tracemalloc程每两分钟记录一次内存分配。这表明分配计数的回报aiohttp/client.py随着时间的推移而增加,最初很快,但随后减慢,直到达到峰值,然后似乎相当稳定。 然而,据观察,如果出现网络问题并且请求开始失败,则计数会再次上升 - 并且在问题解决后不会下降。request()_RequestContextManager

这是泄漏吗?如果是这样,有办法解决吗?

谢谢阅读!