You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Dict memory leak in Python 3.12.x / msgpack 1.0.x #612
I think I've found a second Python 3.12 memory leak (having read the issue for the other one, and tried upgrading to msgpack 1.0.8 to fix).
This issue occurs with dicts, and key uniqueness seems to be a major consideration. (A bunch of dicts with the exact same keys don't cause the problem -- some kind of key caching issue maybe?)
Here's a repro:
import psutil
import msgpack
# Set up a list of packed dicts
p = [
msgpack.packb(
{f'{p}.{r}': True for r in range(1000)}
)
for p in range(1000)
]
# Check initial state
print(f'initial mem: {psutil.Process().memory_info().rss}')
# Loop and unpack
i = 0
for x in p:
y = msgpack.unpackb(x)
i += 1
if i % 100 == 0:
print(f'subsequent mem: {psutil.Process().memory_info().rss}')
The memory leak occurs with both the C version and the fallback version (using Python 3.12).
In the fallback module, if you remove the call to sys.intern, then the leak does not occur. I haven't set up the build, but I assume that if you remove the call to PyUnicode_InternInPlace, then the leak will not occur in the C version.
In Python 3.12, it sounds like all intern'd strings are immortal now. The documentation for intern is out of date at the moment. That explains why memory use continues to go up as an application unpacks dicts with unique keys. All those keys are being kept alive forever.
This ticket explains why msgpack uses intern: #372
Maybe an optional flag could be added to the unpacker, so that applications with many unique keys can opt-out of interning.
This ticket explains why msgpack uses intern: #372
"Many json decoders exploit this and memoize/intern strings, to reduce the memory use of the resulting message"
The irony!
Optional flag sounds like a nice addition; presumably CPython will fix this particular issue at some point but some other case(s) could exist in the future where interning is not appropriate.
Activity
jvs commentedon May 24, 2024
The memory leak occurs with both the C version and the fallback version (using Python 3.12).
In the fallback module, if you remove the call to
sys.intern, then the leak does not occur. I haven't set up the build, but I assume that if you remove the call toPyUnicode_InternInPlace, then the leak will not occur in the C version.I wonder if Python 3.12 has a regression with the table of interned strings.
jvs commentedon May 24, 2024
Sounds related: python/cpython#113993
ThomasWaldmann commentedon May 25, 2024
I also have seen the memory usage going upwards with just the psutil code in the loop.
I didn't compare the magnitude of that with and without the msgpack call though.
jvs commentedon May 25, 2024
In Python 3.12, it sounds like all intern'd strings are immortal now. The documentation for
internis out of date at the moment. That explains why memory use continues to go up as an application unpacks dicts with unique keys. All those keys are being kept alive forever.This ticket explains why msgpack uses intern: #372
Maybe an optional flag could be added to the unpacker, so that applications with many unique keys can opt-out of interning.
amachanic commentedon May 25, 2024
"Many json decoders exploit this and memoize/intern strings, to reduce the memory use of the resulting message"
The irony!
Optional flag sounds like a nice addition; presumably CPython will fix this particular issue at some point but some other case(s) could exist in the future where interning is not appropriate.
methane commentedon Sep 10, 2024
waiting python/cpython#123065
methane commentedon Sep 30, 2024
It is fixed in 3.12.7.