-
Notifications
You must be signed in to change notification settings - Fork 419
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Memory Leak with Async Code #1120
Comments
You see this even with latest cryptography right? I ask because there was a memory leak they fixed in openssl 3.0.3, which we shipped in 37.0.2. |
Ah yes, sorry - I forgot to specify version information: Python: 3.10.4 |
Never the easy answer 😅 |
One more interesting observation using a slightly modified repro: for ctxs in [10, 20, 30, 40, 50, 60, 70, 80, 90, 80, 70, 60, 50, 40, 30, 20, 10]:
asyncio.run(main(ctxs, True))
gc.collect()
print(f"{ctxs=} {proc.memory_info().rss=:>10}")
The relationship between the number of allocated contexts and the memory usage is perfectly linear, it just doesn't go down when reducing the number of contexts. For a regular memory leak, we'd expect it to be superlinear due to the increase in contexts per iteration. Seems like OpenSSL is able to reuse memory, but never lets go of it (?). Edit: More fun stuff: It looks like calling |
What's special to asyncio code here? The certificate handling is exactly the same as the sync version, what changes with asyncio is that BIOs are used instead of sockets for the connection. This should happen even on a sync test. |
Hey folks,
I'm currently debugging a memory leak in mitmproxy which I think is rooted somewhere outside of our codebase. In short:
len(gc.get_objects())
is constant over time._lib.c
1.cat heap.bin | strings | sort | uniq -c | sort -r
./sample.py heap.bin
(random chunks from the heap)All these strings appear somewhere in certifi's CA bundle, so I suspected this is somehow related to us calling
context.load_verify_locations(certifi.where())
. After spending quite some time on this I found python/cpython#84904, which surprisingly reproduces with pyOpenSSL instead of stdlib:Ubuntu 22.04 Output
Windows 10 Output
So yeah - I'm a bit at a loss what's going on here. Any ideas? I think that the call to
load_verify_locations()
may not be the actual suspect, I still see a memory increase when commenting out that line (just much less pronounced). For mitmproxy, it looks like OpenSSL 3 finally has the APIs we need to share contexts more broadly (which should alleviate the problem in our case), but independent of that it looks like something is weirdly wrong here.Footnotes
I've also no idea where
_lib.c
comes from. Maybe I'm missing something, but it looks like there's no such file in either cryptography, cffi, or OpenSSL. ↩The text was updated successfully, but these errors were encountered: