Maison  >  Article  >  développement back-end  >  Comment libérer manuellement la mémoire Python

Comment libérer manuellement la mémoire Python

高洛峰
高洛峰original
2017-03-24 17:37:106367parcourir

Dans l'optimisation ci-dessus, pour 500 utilisateurs, certains calculs seront effectués et les résultats seront enregistrés dans un fichier disque. Au départ, je pensais qu'en faisant cela, ces résultats seraient dans le fichier disque et ne continueraient pas à occuper de la mémoire ; mais en fait, le gros piège de Python est que Python ne nettoiera pas automatiquement ces mémoires ; Ceci est déterminé par sa propre mise en œuvre. Il existe de nombreux articles sur Internet décrivant les raisons spécifiques, je ne les copierai donc pas ici.
Cet article publiera un script expérimental de l'auteur pour illustrer que Python a un tel phénomène de non-libération de mémoire. De plus, une solution est également proposée, à savoir : del d'abord, puis appelez explicitement gc.collect(. ). Script Voir ci-dessous pour les effets spécifiques.
Environnement expérimental un : Win 7, Python 2.7

from time import sleep, time 
import gc 
 
def mem(way=1): 
 print time() 
 for i in range(10000000): 
  if way == 1: 
   pass 
  else: # way 2, 3 
   del i 
    
 print time() 
 if way == 1 or way == 2: 
  pass 
 else: # way 3 
  gc.collect() 
 print time() 
   
if __name__ == "__main__": 
 print "Test way 1: just pass" 
 mem(way=1) 
 sleep(20) 
 print "Test way 2: just del" 
 mem(way=2) 
 sleep(20) 
 print "Test way 3: del, and then gc.collect()" 
 mem(way=3) 
 sleep(20)


Les résultats en cours d'exécution sont les suivants :

Test way 1: just pass 
1426688589.47 
1426688590.25 
1426688590.25 
Test way 2: just del 
1426688610.25 
1426688611.05 
1426688611.05 
Test way 3: del, and then gc.collect() 
1426688631.05 
1426688631.85 
1426688631.95


Pour pour la voie 1 et pour la voie 2, le résultat est exactement le même. La consommation maximale de mémoire du programme est de 326 772 Ko. En veille pendant 20 secondes, la consommation de mémoire en temps réel est de 244 820 Ko.
Pour la voie 3, la consommation maximale de mémoire. du programme est le même que ci-dessus, mais la consommation de mémoire en temps réel pendant le sommeil n'est que de 6 336 Ko.
Environnement expérimental deux : Ubuntu 14.10, Python 2.7.3
Résultats d'exécution :

Test way 1: just pass 
1426689577.46 
1426689579.41 
1426689579.41 
Test way 2: just del 
1426689599.43 
1426689601.1 
1426689601.1 
Test way 3: del, and then gc.collect() 
1426689621.12 
1426689622.8 
1426689623.11
ubuntu@my_machine:~$ ps -aux | grep test_mem 
Warning: bad ps syntax, perhaps a bogus '-'? See http://procps.sf.net/faq.html 
ubuntu 9122 10.0 6.0 270916 245564 pts/1 S+ 14:39 0:03 python test_mem.py 
ubuntu 9134 0.0 0.0 8104 924 pts/2 S+ 14:40 0:00 grep --color=auto test_mem 
ubuntu@my_machine:~$ ps -aux | grep test_mem 
Warning: bad ps syntax, perhaps a bogus '-'? See http://procps.sf.net/faq.html 
ubuntu 9122 10.0 6.0 270916 245564 pts/1 S+ 14:39 0:03 python test_mem.py 
ubuntu 9134 0.0 0.0 8104 924 pts/2 S+ 14:40 0:00 grep --color=auto test_mem 
ubuntu@my_machine:~$ ps -aux | grep test_mem 
Warning: bad ps syntax, perhaps a bogus '-'? See http://procps.sf.net/faq.html 
ubuntu 9122 11.6 0.1 30956 5608 pts/1 S+ 14:39 0:05 python test_mem.py


Conclusion :
La description ci-dessus, Lorsque del est appelé, Python ne libérera pas réellement la mémoire, mais continuera à la placer dans son pool de mémoire ; la mémoire ne sera libérée que lorsque gc.collect() sera explicitement appelé.
Plus loin :
En fait, revenez au script du blog précédent et laissez-le introduire gc.collect(), puis écrivez un script de surveillance pour surveiller la consommation de mémoire :

while ((1)); do ps -aux | sort -n -k5,6 | grep my_script; free; sleep 5; done


Il a été constaté que la mémoire ne sera pas restaurée après l'exécution de 500 groupes d'utilisateurs, mais continuera à être consommée jusqu'à ce qu'il ne reste qu'environ 70 Mo, et gc semble fonctionner. Dans cet environnement, la machine utilise une instance Cloud, la mémoire totale est de 2 Go et la mémoire disponible est d'environ 1 Go. La consommation de mémoire courante de ce script est de 900 Mo - 1 Go. En d'autres termes, pour ce script, gc ne prend pas effet immédiatement, mais lorsque la mémoire disponible du système passe de 1 à 1,2 Go à environ 70 Mo seulement, gc commence à prendre effet. C'est en effet étrange. Je ne sais pas si cela a quelque chose à voir avec le fait que le script utilise gc.collect() dans Thread, ou si la fonction de gc n'est pas contrôlable en premier lieu. L'auteur n'a pas encore fait d'expériences pertinentes et continuera peut-être à en discuter dans le prochain blog.
Cependant, il est certain que si gc.collect() n'est pas utilisé, le script original épuisera la mémoire système et sera tué. Cela ressort clairement du syslog.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn