Open
Description
Bug summary
Calling plt.savefig
leaks local variables from parent calling functions. These can be found in gc.get_objects()
and are cleared by gc.collect()
Code for reproduction
import gc
import matplotlib.pyplot as plt
class SomeObject:
pass
def save_plots():
plt.plot([1, 2, 3])
plt.savefig("test.png")
def leaky():
some_object = SomeObject()
save_plots()
leaky()
for obj in gc.get_objects():
try:
if isinstance(obj, SomeObject):
print("Object is leaking")
except:
pass
Actual outcome
Object is leaking
Expected outcome
Nothing should be printed.
Additional information
- I initially found this bug because I realized my deep learning training loop was leaking VRAM. Torch tensors were being kept in memory when
Figure.savefig
was called - I am under the impression that
ExitStack
withinsavefig
is meant to hack around this issue but is somehow not working in my case? - I have been through issue [Bug]: plt.figure(), plt.close() leaks memory #23701, but here I am able to provide a short and reproducible example
- I have been through Memory leaks on matplotlib 3.4.2 (and 3.4.0) #20490 as well, but the issue persists with the
agg
backend - It is not acceptable to have to call
gc.collect()
. Most users won't be aware of the issue. Given the prevalence of deep learning these days, it's likely objects leaking into GPU memory will be a common problem due to this bug.
Operating system
Win10 x64
Matplotlib Version
3.7.1
Matplotlib Backend
TkAgg
Python version
3.10.0
Jupyter version
No response
Installation
pip
Metadata
Metadata
Assignees
Labels
No labels