la mémoire n'est pas libérée uniquement par plt.close (). Cela devrait être plt.clf () → plt.close ().

emballer

# NG
#La mémoire n'est pas libérée
plt.close()

# OK
#La mémoire est libérée
plt.clf()
plt.close()

# NG
#La mémoire n'est pas libérée lorsque l'ordre est inversé
# plt.close()Si vous fermez la figure avec, vous ne pourrez pas effacer le contenu dessiné.
plt.close()
plt.clf()

Contexte

Lorsque je dessinais des milliers de graphiques à la fois, j'ai eu une erreur de mémoire insuffisante. Parce que je faisais plt.close () '' à chaque fois, je me suis demandé pourquoi et je l'ai étudié par la méthode expérimentale suivante. En conséquence, il a été constaté que la mémoire n'était pas libérée uniquement par plt.close () ''. Et j'ai trouvé que la mémoire est libérée en faisant `` plt.clf () → plt.close () ''.

méthode expérimentale

Tracez un graphique avec une grande taille de mémoire 10 fois de suite. Enregistrez l'utilisation de la mémoire à la fin de chaque tracé et examinez la relation entre le nombre de tracés et l'utilisation de la mémoire. Exécutez cette procédure dans les 4 modèles suivants.

Méthode de post-traitement
modèle 1 plt.clf()
Motif 2 plt.clf() → plt.close()
Modèle 3 plt.close()
Modèle 4 plt.close() → plt.clf()

Cependant, ** redémarrez le noyau à chaque fois pour chaque modèle. ** Ceci permet d'aligner la ligne de base d'utilisation de la mémoire.

Le code pour ce faire est ci-dessous.

import matplotlib.pyplot as plt
import numpy as np
import psutil

mem_ary = []

#Tracer 10 fois
for i in range(10):
    
    #Dessinez un graphique avec une grande taille de mémoire
    x = np.arange(1e7)
    y = np.arange(1e7)
    plt.plot(x, y)
    
    # ===================================================
    #Exécutez l'un des modèles 1 à 4 suivants
    #Commentez le reste
    # ===================================================

    #modèle 1
    plt.clf()
    
    #Motif 2
    plt.clf()
    plt.close()
    
    #Modèle 3
    plt.close()
    
    #Modèle 4
    plt.close()
    plt.clf

    # ===================================================

    #Enregistrer l'utilisation de la mémoire
    mem = psutil.virtual_memory().used / 1e9
    mem = round(mem, 1)
    mem_ary.append(mem)

Résultats et conclusions

Les résultats sont résumés dans le graphique ci-dessous.

スクリーンショット 2020-06-01 午後11.38.11.png

Seulement plt.clf () → plt.close () '', l'utilisation de la mémoire n'a pas augmenté. Par conséquent, vous pouvez voir que plt.clf () → plt.close () '' devrait être fait.

De plus, si vous inversez l'ordre et sélectionnez plt.close () → plt.clf () '', la mémoire ne sera pas libérée. Vous devez être prudent. Je pense que la cause est probablement que si vous fermez la figure avec plt.close () '', vous ne pourrez pas effacer le contenu du dessin. (Référence: Official DOC of plt.close (), [Official DOC of plt.clf ()](https: // matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.close))

version

matplotlib:3.2.1

Recommended Posts

la mémoire n'est pas libérée uniquement par plt.close (). Cela devrait être plt.clf () → plt.close ().
S'il n'est pas facile à comprendre, il ne peut pas être amélioré.
J'ai entendu des rumeurs selon lesquelles malloc est lent et devrait être stocké en mémoire, alors je l'ai comparé.