80 votes

Comment puis-je libérer de la mémoire après avoir créé des figures de matplotlib

J'ai plusieurs fonctions matlpotlib intégrées dans certaines tâches django-celery.

Chaque fois que les tâches sont appelées, plus de RAM est dédiée à python. Avant longtemps, python occupe toute la mémoire vive.

QUESTION : Comment puis-je libérer ce souvenir ?

UPDATE 2 - Une deuxième solution :

J'ai posé une question similaire concernant spécifiquement la mémoire bloquée lors des erreurs de matplotlib, mais j'ai obtenu une bonne réponse à cette question .clf() , .close() et gc.collect() ne sont pas nécessaires si vous utilisez multiprocess pour exécuter la fonction de traçage dans un processus séparé dont la mémoire sera automatiquement libérée une fois le processus terminé.

Les erreurs de Matplotlib entraînent une fuite de mémoire. Comment puis-je libérer cette mémoire ?

UPDATE - La solution :

Ces posts stackoverflow suggèrent que je peux libérer la mémoire utilisée par les objets matplotlib avec les commandes suivantes :

.clf() : Matplotlib manque de mémoire lors d'un tracé en boucle

.close() : Python matplotlib : mémoire non libérée lors de la spécification de la taille des figures

import gc
gc.collect()

Voici l'exemple que j'ai utilisé pour tester la solution :

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from pylab import import figure, savefig
import numpy as np
import gc      

a = np.arange(1000000)
b = np.random.randn(1000000)

fig = plt.figure(num=1, dpi=100, facecolor='w', edgecolor='w')
fig.set_size_inches(10,7)
ax = fig.add_subplot(111)
ax.plot(a, b)

fig.clf()
plt.close()
del a, b
gc.collect()

6voto

Nicolae Dascalu Points 1329

Avez-vous essayé d'exécuter votre fonction de tâche plusieurs fois (dans un for) pour être sûr que votre fonction ne fuit pas quelle que soit la célérité ? Assurez-vous que la valeur de django.settings.DEBUG est False (l'objet de connexion conserve toutes les requêtes en mémoire lorsque DEBUG=True).

0 votes

Bonnes suggestions. DEBUG était réglé sur false. J'ai exécuté la fonction plusieurs fois dans une boucle for et il semble que la fuite de mémoire soit associée à mon code. Auparavant, j'avais cette fonction en tant que vue django, mais le temps de demande http était trop long, alors je l'ai déplacé vers une tâche django-celery. Je pense que django a un bon nettoyage de la mémoire pour toutes les requêtes http, ce dont je ne bénéficie plus maintenant que c'est une tâche. Malheureusement, je ne vois pas d'où vient la fuite de mémoire. J'essaie de supprimer les variables que j'ai déclarées dans la fonction pour libérer cette mémoire lorsque j'ai terminé mais cela ne semble pas avoir d'effet.

2voto

import matplotlib.pyplot as plt
from datetime import datetime
import gc

class MyClass:
    def plotmanytimesandsave(self):
        plt.plot([1, 2, 3])
        ro2 = datetime.now()
        f =ro2.second
        name =str(f)+".jpg"
        plt.savefig(name)
        plt.draw()
        plt.clf()
        plt.close("all")

for y in range(1, 10):
    k = MyClass()
    k.plotmanytimesandsave()
    del k
    k = "now our class object is a string"
    print(k)
    del k
    gc.collect

Avec ce programme, vous pourrez enregistrer directement autant de fois que vous le souhaitez sans la commande plt.show(). Et la consommation de mémoire sera faible.

0 votes

Excellente solution !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X