2009-04-17 7 views
0

link textpoursuite sys.getrefcount

Je suis le concept du compte de référence

Alors, quand je fais un « del astrd », le nombre de référence tombe à zéro et astrd obtient recueilli par gc?

Ce sont les codes échantillon de codes.These j'ai développé après la question de mon hier: link text

one.py:

def abc():

print "Hello" 
print "123" 
print '345' 

two.py:

import one 
#reload(one) 

#def defg(): 

one.abc() 

trois.py:

import os,sys,gc 
from time import sleep 

import two 
#reload(two) 
#two.defg() 

sleep(20) 


directory = os.listdir('.') 

for filename in directory: 

     if filename[-3:] == 'pyc': 

       print '- ' + filename 

       print sys.getrefcount(filename) 

       file_name = os.path.splitext (filename)[0] 

       del file_name # remove the local reference 

       del sys.modules[os.path.splitext (filename)[0]] # removes import 

       gc.collect() # garbage collect 

       #del sys.modules[filename] 

       #del filename 

       #os.remove(filename) 

Ce que j'ai fait dans three.py est correct ou non? Y a-t-il des étapes inutiles? Si oui, pourquoi?

Aidez-moi s'il vous plaît à m'en sortir.

Répondre

6

Je crois que la mémoire est automatiquement libéré le moment refcount atteint zéro. Le GC n'est pas impliqué.

Le GC python est facultatif et n'est utilisé que s'il existe des objets inaccessibles ayant des cycles de référence. En fait, vous pouvez appeler gc.disable() si vous êtes sûr que votre programme ne crée pas de cycles de référence.

Quant à la question initiale:

  • Lorsque vous faites del astrd, vous supprimez la liaison de astrd de l'espace de noms local une référence à un objet (quel que soit les références astrd).
  • Si cela signifie que le refcount est zéro, la mémoire utilisée par l'objet est libérée. Donc, del ne supprime pas les objets, il délie les références. La suppression d'objets est un effet secondaire qui se produit si la liaison d'une référence provoque l'échec du compte refcount.

Notez que ce qui précède n'est vrai que pour CPython. Jython et IronPython utilisent le mécanisme GC JVM/CLR, et n'utilisent pas du tout le refcounting, je crois.

Le pratique gc.get_objects renvoie une liste de toutes les instances d'objet suivies par l'interpréteur Python. Exemple:

 
import gc 

class test(object): 
    pass 

def number_of_test_instances(): 
    return len([obj for obj in gc.get_objects() if isinstance(obj, test)]) 

for i in range(100): 
    t = test() 

print "Created and abandoned 100 instances, there are now", \ 
    number_of_test_instances(), \ 
    "instances known to the python interpreter." 

# note that in normal operation, the GC would 
# detect the unreachable objects and start 
# collecting them right away 
gc.disable() 

for i in range(100): 
    t = test() 
    t.t = t 

print "Created and abandoned 100 instances with circular ref, there are now", \ 
    number_of_test_instances(), \ 
    "instances known to the python interpreter." 

gc.collect() 
print "After manually doing gc.collect(), there are now", \ 
    number_of_test_instances(), \ 
    "instances known to the python interpreter." 

L'exécution de ce programme donne:

 
Created and abandoned 100 instances, there are now 1 instances known to the python interpreter. 
Created and abandoned 100 instances with circular ref, there are now 100 instances known to the python interpreter. 
After manually doing gc.collect(), there are now 1 instances known to the python interpreter. 
+0

m éditer ma question en joignant un code par exemple pouvez-vous me dire wts hppng n ai-je raison? – user46646

+0

Qu'essayez-vous d'accomplir dans votre code? – codeape

+0

Selon ma question d'hier j'essayais de supprimer les importations J'ai joint le deuxième lien – user46646

0

Pourriez-vous donner quelques informations à ce que vous faites? Il y a rarement une raison pour utiliser explicitement del sur des variables autres que pour nettoyer un espace de noms de choses que vous ne voulez pas exposer. Je ne sais pas pourquoi vous appelez del file_name ou en cours d'exécution gc.collect().

Pour les objets dont l'heure exacte est finalisée (p.ex. fonction finit, il sera recueilli, et il ne causera aucun mal jusque-là. Appeler manuellement del pour de telles variables encombre simplement votre code.

Pour les objets qui doivent être finalisés immédiatement (par exemple, un fichier ouvert ou un verrou en attente), vous ne devriez pas compter sur le garbage collector de toute façon - il n'est pas garanti de collecter immédiatement de tels objets. Il arrive à le faire dans l'implémentation standard de C python, mais pas dans Jython ou IronPython, et n'est donc pas garanti. Au lieu de cela, vous devez nettoyer explicitement ces objets en appelant close ou en utilisant la nouvelle construction with. La seule autre raison pourrait être que vous avez une très grande quantité de mémoire allouée, et que vous voulez signaler que vous en avez fini avec la variable qui s'y rapporte qui sort naturellement de la portée.

Votre exemple ne semble pas correspondre à l'une de ces circonstances, donc je ne sais pas pourquoi vous appelez manuellement le garbage collector.