question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Memory leak when using `set_type_codec` and Python 3.10

See original GitHub issue
  • asyncpg version: 0.25.0
  • PostgreSQL version: 13, 14
  • Do you use a PostgreSQL SaaS? If so, which? Can you reproduce the issue with a local PostgreSQL install?: Reproduced locally
  • Python version: 3.10.1
  • Platform: Linux
  • Do you use pgbouncer?: no
  • Did you install asyncpg with pip?: yes
  • If you built asyncpg locally, which version of Cython did you use?:
  • Can the issue be reproduced under both asyncio and uvloop?:

The test I’m running: https://github.com/roman-g/asyncpg-memory-leak

Basically there’s a table with a JSONB column, if I call await connection.set_type_codec("jsonb", encoder=json.dumps, decoder=json.loads, schema="pg_catalog"), each SELECT including that column causes a memory leak.

The test fetches all rows 2000 times, then calls set_type_codec, repeats reading, reports memory usage in MB between stages. The reported usage is like

24
24
89

indicating a massive growth after the last reading.

SqlAlchemy always calls set_type_codec, so the issue affects it by default.

import asyncio
import os
import psutil
import asyncpg
import json


async def main():
    connection = await asyncpg.connect('postgresql://postgres:some_secret@postgresql:5432/postgres')
    await prepare_data(connection)

    print_memory_usage_in_mb()
    await read(connection)
    print_memory_usage_in_mb()

    await connection.set_type_codec("jsonb", encoder=json.dumps, decoder=json.loads, schema="pg_catalog")

    await read(connection)
    print_memory_usage_in_mb()

    await connection.close()


async def prepare_data(connection):
    await connection.execute("DROP TABLE IF EXISTS some_table")
    await connection.execute("""
        CREATE TABLE some_table(
            id serial PRIMARY KEY,
            data jsonb
        )
    """)
    for i in range(1000):
        await connection.execute("INSERT INTO some_table(data) VALUES($1)", '{"key":"value"}')


async def read(connection):
    for i in range(2000):
        result = await connection.fetch("SELECT data FROM some_table")
        assert len(result) > 0


def print_memory_usage_in_mb():
    process = psutil.Process(os.getpid())
    print(round(process.memory_info().rss / 1000000))


asyncio.run(main())

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:1
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

5reactions
elpranscommented, Jan 11, 2022

@1st1 was able to find the actual memory leak in the aforementioned commit, which should be fixed by https://github.com/python/cpython/pull/30546. The leak is in PyEval_EvalFrameEx, which is not used by Python itself, but is used by Cython, though only under Python 3.10 and earlier, which explains why Python 3.11 wasn’t affected.

Thanks for reporting the issue!

0reactions
eirnymcommented, Jan 11, 2022

@elprans thank you for the details!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Issue 46347: memory leak in PyEval_EvalCodeEx
I'm investigating a memory leak in 3.10, and while looking at the offending commit I stumbled upon this: in ceval.c:PyEval_EvalCodeEx, ...
Read more >
How can I prevent this memory leak? - python - Stack Overflow
The memory leak persists. I'm using Python 3.10.2 on Windows 10. C++ is being compiled by Visual Studio to the C++14 standard.
Read more >
Memory Leak in Python requests - GeeksforGeeks
Whether it be REST APIs or Web Scrapping, requests are must be learned for proceeding further with these technologies. When one makes a...
Read more >
GitHub statistics for 3.5.2 (May 02, 2022) - Matplotlib
PR #22002: Fix TkAgg memory leaks and test for memory growth regressions ... PR #22764: Backport PR #22756 on branch v3.5.x (Use system ......
Read more >
Huge memory leakage issue with tf.keras.models.predict()
But this is not why paid hefty money for the GPU cores! just FYI, TF2.10/METAL-0.6 with python 3.10.6 in CPU mode got me...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found