Closed adamgregory closed 1 year ago
If @adamgregory isn't ineterested, I would like to take this up. I noticed that this also works with sqlite:///:memory:
engine, so easy to reproduce locally.
Quick check indicates it's probably related to this commit.
Please go ahead. I haven't been able to make much progress here beyond identifying the issue. Compared to 0.36b0 these additional listeners introduce more circular memory references between Engine and EngineTracer, but this is definitely not my area of expertise and it wasn't clear to me why the garbage collector wasn't able to detect and free these circular references.
It looks like the gist of the issue is this line. Each new engine gets appended to cls._remove_event_listener_params
via the target
parameter, and so this list keeps holding references until uninstrument()
is called. Need to check in sqlalchemy
code if there's another alternative.
Describe your environment python 3.9.7
Steps to reproduce
output:
What is the expected behavior? After fetching the data the engine is disposed to ensure all of the pooled connections are fully closed. Related objects should be garbage collected after they fall out of scope
What is the actual behavior? Despite manually invoking the garbage collector interface, one instance of the sqlalchemy or sqlalchemy instrumentation related objects remains allocated in memory for each time the
leak_memory
function was executed. If theleak_memory
function is run in an infinite loop the memory allocated to the script will grow linearly and unbounded until available memory is consumed.Additional context This issue was introduced in 0.37b0 and is also present in 0.38b0