2008-08-26 18 views
16

Si j'appelle finalize() sur un objet de mon code de programme, le JVM réexécutera-t-il la méthode quand le garbage collector traite cet objet?Java et exécution manuelle finalize

Ce serait un exemple approximative:

MyObject m = new MyObject(); 

m.finalize(); 

m = null; 

System.gc() 

Est-ce que l'appel explicite à finalize() rendre le garbage collector de machine virtuelle Javane pas exécuter la méthode finalize() sur l'objet m?

Répondre

30

Selon ce programme de test simple, la machine virtuelle Java va encore faire son appelez pour finaliser(), même si vous avez appelé explicitement:

La sortie est:

début
finaliser!
finaliser!
fait

Chaque ressource dit là-bas pour appeler jamais finaliser() explicitement, et à peu près jamais mettre en œuvre la méthode même parce qu'il n'y a aucune garantie quant à savoir si et quand il sera appelé. Il vaut mieux simplement fermer toutes vos ressources manuellement.

1

La méthode finalize n'est jamais appelée plus d'une fois par une machine virtuelle Java pour un objet donné. Vous ne devriez pas compter sur finaliser de toute façon, car il n'y a aucune garantie qu'il sera invoqué. Si vous appelez finalise parce que vous devez exécuter le code de nettoyage alors mieux le mettre dans une méthode distincte et la rendre explicite, par exemple:

public void cleanUp() { 
    . 
    . 
    . 
} 

myInstance.cleanUp(); 
6

Vous devez comprendre le flux de travaux Garbage Collector (GC) pour comprendre la fonction de finalisation. appeler .finalize() n'invoquera pas le garbage collector, ni n'appellera system.gc. En fait, ce que finalise aidera le codeur à déclarer la référence de l'objet comme "non référencé".

Le GC force une suspension sur l'opération de fonctionnement de la JVM, ce qui nuit aux performances. Pendant le fonctionnement, GC parcourra tous les objets référencés, à partir de l'objet racine (votre appel de méthode principal). Ce temps de suspension peut être diminué en déclarant les objets comme étant non référencés manuellement, car cela réduira les coûts d'opération pour déclarer la référence d'objet obsolète par l'exécution automatisée. En déclarant finalize(), le codeur met la référence à l'objet obsolète, ainsi lors de la prochaine exécution du fonctionnement du GC, GC run balayera les objets sans utiliser le temps de fonctionnement.

"Après que la méthode finalize a été invoquée pour un objet, aucune autre action n'est entreprise tant que la machine virtuelle Java n'a pas encore déterminé qu'il n'y a plus aucun moyen d'accéder à cet objet par un thread ayant pas encore mort, y compris les actions possibles par d'autres objets ou classes qui sont prêts à être finalisés, à quel point l'objet peut être supprimé. "à partir de Java API Doc sur java.Object.finalize();

Pour une explication détaillée, vous pouvez également vérifier: javabook.computerware