Skip to content

Memory leak for simple get call #4618

Closed
@dima-kov

Description

@dima-kov

🐞 Describe the bug

I have faced with memory leak in my program: after loading 100k URLs the process eats additional 300mb of RAM. I had extracted this piece of code, that reproduces memory issue (below) and ran it with mprof for 5 min for loading 4k urls:

aiohttp-memory-leak

💡 To Reproduce

Use env:

aiohttp==4.0.0a1
async-timeout==3.0.1
attrs==19.3.0
chardet==3.0.4
cycler==0.10.0
idna==2.9
kiwisolver==1.1.0
matplotlib==3.2.0
memory-profiler==0.57.0
multidict==4.7.5
numpy==1.18.1
psutil==5.7.0
pyparsing==2.4.6
python-dateutil==2.8.1
six==1.14.0
typing-extensions==3.7.4.1
uvloop==0.14.0
yarl==1.4.2

Tested with different versions of aiohttp (>3.5)

Code:

import asyncio
import uvloop
import aiohttp

url = 'https://docs.mapbox.com/mapbox-gl-js/assets/earthquakes.geojson'

load_times = 4000


def get_to_load():
    global load_times
    if load_times > 0:
        load_times -= 1
        return url
    return None


async def fetch(session, url):
    response = await session.get(url)
    return await response.text()


async def load(session, worker_id):
    to_load = get_to_load()
    while to_load is not None:
        r = await fetch(session, to_load)
        print('Done', worker_id)
        await asyncio.sleep(0.2)
        to_load = get_to_load()


async def main(workers_num=90):
    async with aiohttp.ClientSession() as session:
        await asyncio.gather(*[load(session, i) for i in range(workers_num)])


asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
loop = asyncio.get_event_loop()

asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
asyncio.run(asyncio.sleep(3))
asyncio.run(main())
asyncio.run(asyncio.sleep(5))
  1. Run for 5 min with profiler.

💡 Expected behavior
Keep memory usage near straight during the whole program run.

📋 Your version of the Python
Python 3.7.5 (Also tested on 3.8)

📋 Your version of the aiohttp/yarl/multidict distributions

  • aiohttp:
Name: aiohttp
Version: 4.0.0a1
  • yarn:
Name: yarl
Version: 1.4.2
  • multidict
Name: multidict
Version: 4.7.5

📋 Additional context
I have read all issues related to memory leaks, but have not found any appropriate solution. Here are what I tried:

  • update all packages
  • aiohttp 4.0
  • python 3.8
  • uvloop implementation instead of asyncio
  • single aiohttp.ClientSession instead of new on every request (actually, this gave a bit increase)

📋 Enviroment

  • OSX
ProductVersion: 10.15.1
BuildVersion:   19B88
  • also ran in docker (linux) - the same

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions