J'étais en train de parcourir de vieux livres et j'ai trouvé une copie de "Practical Java" de Peter Hagger. Dans la section performances, il existe une recommandation pour définir des références d'objet null
lorsqu'elles ne sont plus nécessaires.
En Java, la définition de références d'objet pour null
améliorer les performances ou l'efficacité du garbage collection? Si oui, dans quels cas est-ce un problème? Classes de conteneurs? Composition d'objets? Classes internes anonymes?
Je vois cela assez souvent dans le code. Ce conseil de programmation est-il désormais obsolète ou est-il toujours utile?
Réponses:
Cela dépend un peu du moment où vous envisagez d'annuler la référence.
Si vous avez une chaîne d'objets A-> B-> C, une fois que A n'est pas joignable, A, B et C seront tous éligibles pour le garbage collection (en supposant que rien d'autre ne fait référence à B ou C). Il n'est pas nécessaire, et n'a jamais été nécessaire, de définir explicitement les références A-> B ou B-> C à null, par exemple.
En dehors de cela, la plupart du temps, le problème ne se pose pas vraiment, car en réalité, vous avez affaire à des objets dans des collections. Vous devriez généralement toujours penser à supprimer des objets des listes, des cartes, etc. en appelant la méthode remove () appropriée.
Le cas où il y avait des conseils pour définir des références à null était spécifiquement dans une longue portée où un objet gourmand en mémoire cessait d'être utilisé à mi-chemin dans la portée . Par exemple:
Le raisonnement ici était que parce que obj est toujours dans la portée, alors sans l'annulation explicite de la référence, il ne devient pas récupérable avant la fin de la méthode doSomethingElse () . Et c'est le conseil qui ne tient probablement plus sur les JVM modernes : il s'avère que le compilateur JIT peut déterminer à quel point une référence d'objet local donnée n'est plus utilisée.
la source
Non, ce n'est pas un conseil obsolète. Les références pendantes sont toujours un problème, surtout si vous implémentez, par exemple, un conteneur de tableau extensible (
ArrayList
ou similaire) en utilisant un tableau pré-alloué. Les éléments au-delà de la taille "logique" de la liste doivent être annulés, sinon ils ne seront pas libérés.Voir Effective Java 2nd ed, Item 6: Eliminate Obsolete Object References.
la source
Champs d'instance, éléments de tableau
S'il existe une référence à un objet, il ne peut pas être récupéré. Surtout si cet objet (et tout le graphique derrière) est gros, il n'y a qu'une seule référence qui arrête le ramasse-miettes, et cette référence n'est plus vraiment nécessaire, c'est une situation malheureuse.
Les cas pathologiques sont l'objet qui conserve une instance unnessary à l'ensemble de l'arborescence DOM XML qui a été utilisée pour le configurer, le MBean qui n'a pas été désenregistré, ou la référence unique à un objet d'une application Web non déployée qui empêche tout un chargeur de classe d'être déchargé .
Donc, à moins que vous ne soyez sûr que l'objet qui contient la référence lui-même sera de toute façon récupéré (ou même alors), vous devez annuler tout ce dont vous n'avez plus besoin.
Variables de portée:
Si vous envisagez de définir une variable locale sur null avant la fin de sa portée, afin qu'elle puisse être récupérée par le garbage collector et la marquer comme "inutilisable à partir de maintenant", vous devriez plutôt envisager de la placer dans une portée plus limitée. .
devient
Les portées longues et plates sont généralement mauvaises pour la lisibilité du code. Il n'est pas rare non plus d'introduire des méthodes privées pour briser les choses juste à cette fin.
la source
Dans les environnements à mémoire restreinte (par exemple les téléphones portables), cela peut être utile. En définissant null, l'objetc n'a pas besoin d'attendre que la variable soit hors de portée pour être gc'd.
Pour la programmation de tous les jours, cependant, cela ne devrait pas être la règle, sauf dans des cas particuliers comme celui cité par Chris Jester-Young.
la source
Premièrement, cela ne signifie rien sur lequel vous définissez un objet
null
. Je l'explique ci-dessous:Dans le segment de code ci-dessus, nous créons le nom
list1
de la variable de référence d'ArrayList
objet de l' objet qui est stocké dans la mémoire. Donclist1
fait référence à cet objet et ce n'est rien de plus qu'une variable. Et dans la deuxième ligne de code, nous copions la référence delist1
tolist2
. Revenons maintenant à votre question si je le fais:cela signifie qu'il
list1
ne fait plus référence à aucun objet qui est stocké dans la mémoire etlist2
n'aura donc plus rien à référencer. Donc, si vous vérifiez la taille delist2
:Alors voilà le concept de ramasse-miettes qui dit «vous n'avez pas à vous soucier de libérer la mémoire qui est détenue par l'objet, je le ferai quand je constaterai qu'il ne sera plus utilisé en programme et que JVM me gérera.»
J'espère que le concept est clair.
la source
L'une des raisons pour cela est d'éliminer les références d'objet obsolètes. Vous pouvez lire le texte ici.
la source