2010-11-18 23 views
14

C'est surtout par curiosité.Bonnes utilisations de la méthode finalize()

J'étais errant si quelqu'un a rencontré un bon usage pour Object.finalize() à l'exception de débogage/consignation/profilage?

Si vous n'en avez pas rencontré, que diriez-vous qu'un bon usage serait?

+2

Vous pouvez l'utiliser comme butée de porte, ou une ancre de bateau :-) –

+0

: D voulez-vous dire son assez lourd ou qu'il ne flotte pas? – Simeon

Répondre

7

Si votre objet Java utilise JNI pour indiquer au code natif d'allouer de la mémoire native, vous devez utiliser finalize pour vous assurer qu'il est libéré.

+0

Quelqu'un est-il en désaccord avec cela? – bmargulies

+1

Pourquoi ne pouvez-vous pas gérer la mémoire native comme toutes les autres ressources (fichiers ouverts, connexions DB) et exiger une fermeture explicite? Votre objet Java pourrait simplement avoir 'disposer()' ou 'close()' qui effectue le nettoyage. – sleske

+1

Ces choses ont généralement des finaliseurs. 'close()' vous permet de libérer les ressources plus tôt, mais la JVM utilise toujours un finaliseur pour garantir leur libération éventuelle. – bmargulies

2

Je l'utilise pour réécrire des données dans une base de données lors de l'utilisation de références logicielles pour la mise en cache d'objets supportés par une base de données.

+4

Vous devriez laisser une bibliothèque s'occuper de ces choses. – aioobe

+4

Oui. Je sais ... – aioobe

+1

: D m'a fait rire ... – Simeon

3
  1. fermer les connexions externes (db, socket etc)
  2. fichiers ouverts près. peut-être même essayer d'écrire des informations supplémentaires.
  3. consignation
  4. Si cette classe exécute des processus externes qui doivent exister uniquement lorsque l'objet existe, vous pouvez essayer de les supprimer ici.

Mais il est juste une solution de repli qui est utilisé est le mécanisme « normal » ne fonctionne pas. Le mécanisme normal devrait être initié explicitement.

+0

Vraiment important à utiliser uniquement comme protection contre le code buggy. Les systèmes d'exploitation limitent le nombre de fichiers ouverts par processus, vous risquez de manquer de gestionnaires de fichiers bien avant l'appel de finalize(). – josefx

+2

Fermez les fichiers ouverts lors de la finalisation? Puisque finalize ne peut jamais être appelé pendant la durée de vie de l'application, êtes-vous sûr que c'est une bonne idée? Je dirais que vous devez fermer les fichiers ouverts dans un bloc finally (ou quelque chose que vous êtes sûr d'avoir exécuté). – Simeon

+0

@Simeon Je pense qu'AlexR voulait dire que ce sont des solutions de repli (comme il l'a dit dans sa réponse) au cas où les fichiers ne seraient pas fermés au moment où ils étaient supposés l'être. tout le temps. – blwy10

2

Libère les ressources qui devraient être libérées manuellement dans des circonstances normales, mais qui n'ont pas été libérées pour une raison quelconque. Peut-être avec écrire un avertissement au journal.

+0

Ooh, écrire à un journal est une bonne idée.Ensuite, vous obtenez non seulement la chose libérée, mais vous obtenez un avertissement sur le problème. Je n'ai jamais pensé à ça. J'ai une classe que je devrais faire changer ... – Jay

-1

Je vois un bon usage pour finaliser(): libérer des ressources qui sont disponibles en grandes quantités et ne sont pas exclusifs. Par exemple, par défaut, 1024 handles de fichiers sont disponibles pour un processus Linux et environ 10000 pour Windows. Par défaut, C'est à peu près, donc pour la plupart des applications, si vous ouvrez un fichier, vous n'avez pas besoin d'appeler .close() (et d'utiliser les blocs try ... finally), et vous serez OK - enfin() Libérez-le pour vous quelque temps plus tard. Cependant, pour certaines parties de code (comme les applications serveur intensives), libérer des ressources avec .close() est un must, sinon finally() peut être appelé trop tard pour vous et vous risquez de manquer de handles de fichiers. La même technique est utilisée par Swing - les ressources du système d'exploitation pour afficher les fenêtres et le dessin ne sont pas libérées par une méthode .close(), mais simplement par finalize(), donc vous n'avez pas à vous soucier de tout. Les méthodes close() ou .dispose() comme dans SWT par exemple. Toutefois, lorsque le nombre de ressources est très limité ou que vous devez verrouiller la ressource pour l'utiliser, n'oubliez pas de la déverrouiller. Par exemple si vous créez un verrou de fichier sur un fichier, n'oubliez pas de supprimer ce verrou, sinon personne ne pourra lire ou écrire ce fichier et cela peut conduire à des blocages - alors vous ne pouvez pas compter sur finalize() pour supprimer cette serrure pour vous - vous devez le faire manuellement au bon endroit.

+1

-1: c'est la hauteur de l'impolitesse pour une application de se fier au finaliseur pour fermer un descripteur de fichier, quand il est si facile d'appeler 'close()'. –

+1

L'appel de .close() n'est pas du tout facile: la gestion à 100% de close nécessite deux clauses try ... (un essai ... enfin ivoke close(), et close() invocation doit être inclus avec try ... catch, qui devrait alors enregistrer l'erreur pour éviter de perdre l'exception d'origine), plus vous travaillez sur des fichiers, la situation est pire, par exemple travailler avec deux fichiers en même temps nécessite 4 try ... catch blocs - quel gâchis maintenant comparer cela avec la facilité de travailler avec des fichiers dans les langages de script, comme Perl par exemple - vous ne devez pas appeler close() dans tous les lieux! – iirekm

5

retard à la fête ici, mais je pensais encore à carillon:

Une des meilleures utilisations que j'ai trouvé pour finalizers est d'appeler des méthodes de terminaison explicites qui, pour une raison quelconque, ne sont pas appelés. Lorsque cela se produit, nous enregistrons également le problème car il s'agit d'un BUG!

Parce que:

  • Il n'y a aucune garantie que finaliseurs seront exécutées rapidement (ou techniquement du tout), par la spécification du langage
  • d'exécution dépend en grande partie sur la mise en œuvre de la machine virtuelle Java
  • exécution peut parfois être retardé si le GC a une priorité de fil inférieure

Cela ne laisse qu'une poignée de tâches qu'ils peuvent traiter sans trop de risques.

+0

Très utile, merci :) – Simeon