-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Open
Labels
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