web-dev-qa-db-fra.com

Comment détruire un objet en Java?

J'ai rencontré cette question dans une interview avec les options suivantes:

Comment détruire un objet en java?

a. System.gc();  
b. Runtime.getRuntime.gc();  
c. object.delete();  
d. object.finalize();  
e. Java performs gc by itself, no need to do it manually.
  1. La réponse devrait être e?

  2. et si e n'était pas là? puis ? clairement c n'est pas la réponse. a et b feront gc pour toute l'application (la question nécessite pour un objet). Je pense que c’est parce que finalize () est appelé juste avant gc (mais est-il nécessaire qu’après que finalize gc soit invoqué?) Ou j’ai tort? Vous devez être là pour répondre à cette question?

41
nr5

La réponse E est la réponse correcte. Si E n'est pas là, vous manquerez bientôt de mémoire (ou) Pas de réponse correcte.

L'objet doit être inaccessible pour être éligible au GC. JVM effectue plusieurs analyses et déplace des objets d'une génération à l'autre pour déterminer l'éligibilité du CPG et libère la mémoire lorsque les objets ne sont pas accessibles.

53
kosa

Pour clarifier pourquoi les autres réponses ne peuvent pas fonctionner:

  1. System.gc() (avec Runtime.getRuntime().gc(), qui fait exactement la même chose) indique que vous souhaitez que des éléments soient détruits. Vaguement. La JVM est libre d'ignorer les demandes d'exécution d'un cycle de catalogue global, si elle n'en voit pas la nécessité. De plus, à moins que vous n'annuliez toutes les références accessibles à l'objet, GC ne le touchera pas de toute façon. Donc, A et B sont tous deux disqualifiés.

  2. Runtime.getRuntime.gc() est une mauvaise grammaire. getRuntime est une fonction, pas une variable; vous avez besoin de parenthèses pour l'appeler. Donc B est double disqualifié.

  3. Object n'a pas de méthode delete. Donc C est disqualifié.

  4. Bien que Object ait une méthode finalize, il ne détruit rien. Seul le ramasse-miettes peut réellement supprimer un objet. (Et dans de nombreux cas, techniquement, ils ne se donnent même pas la peine de faire cela , ils ne le copient pas quand ils font les autres, donc il est laissé derrière.) Tout finalize fait est de donner à un objet une chance de nettoyer avant La machine virtuelle Java le supprime. De plus, vous ne devriez jamais appeler finalize directement. (Comme finalize est protégé, la JVM ne vous laissera pas l'appeler de toute façon sur un objet arbitraire.) Donc, D est disqualifié.

  5. En plus de tout cela, object.doAnythingAtAllEvenCommitSuicide() nécessite que le code en cours ait une référence à object. Cela seul le rend "vivant" et donc inéligible pour le ramassage des ordures. Donc C et D sont double disqualifiés.

31
cHao

Réponse courte - E

La réponse est E étant donné que le reste est manifestement faux, mais ..

Réponse longue - Ce n'est pas si simple. ça dépend ...

Le simple fait est que le ramasse-miettes ne peut jamais décider de ramasser le ramassage pour chaque objet qui est un candidat viable pour le ramasser, sauf si la pression de la mémoire est extrêmement élevée. Et puis il y a le fait que Java est tout aussi sensible à les fuites de mémoire comme tout autre langage, ils sont simplement plus difficiles à provoquer, et donc plus difficiles à trouver quand vous les causez!

L'article suivant contient de nombreux détails utiles sur le fonctionnement de la gestion de la mémoire et sur le fonctionnement de celui-ci. Fonctionnement des récupérateurs de mémoire de génération et Merci pour la mémoire (Comprendre comment la machine virtuelle utilise la mémoire native sous Windows et Linux)

Si vous lisez les liens, je pense que vous aurez l'idée que la gestion de la mémoire dans Java n'est pas aussi simple qu'une question à choix multiples .

17
user177800

Définissez sur null. Ensuite, il n'y a plus de références et l'objet deviendra éligible pour le ramassage des ordures. GC supprimera automatiquement l’objet du tas.

7
user1843495

Voici le code:

public static void main(String argso[]) {
int big_array[] = new int[100000];

// Do some computations with big_array and get a result. 
int result = compute(big_array);

// We no longer need big_array. It will get garbage collected when there
// are no more references to it. Since big_array is a local variable,
// it refers to the array until this method returns. But this method
// doesn't return. So we've got to explicitly get rid of the reference
// ourselves, so the garbage collector knows it can reclaim the array. 
big_array = null;

// Loop forever, handling the user's input
for(;;) handle_input(result);
}
4
Mathan

Dans Java, il n'y a pas de moyen explicite de procéder à la récupération de place. La machine virtuelle elle-même exécute des threads en arrière-plan, recherchant les objets ne contenant aucune référence, ce qui signifie tous les moyens d'accéder à l'objet. D'autre part, un objet est également éligible pour le garbage collection s'il est épuisé. Le programme dans lequel nous avons créé l'objet est terminé ou se termine. Pour répondre à votre question, la méthode finalize est identique au destructeur en C++. La méthode finalize est effectivement appelée par la machine virtuelle Java juste avant d'effacer la mémoire de l'objet. Il vous appartient de définir ou non la méthode finalize dans votre programme. Toutefois, si le garbage collection de l'objet est effectué après le programme terminé, la machine virtuelle Java n'invoquera pas la méthode finalize définie dans votre programme. Vous pouvez vous demander à quoi sert la méthode finalize? Par exemple, considérons que vous avez créé un objet nécessitant un flux vers un fichier externe et ex a défini de manière explicite une méthode de finalisation à cet objet, qui vérifie si le flux est ouvert dans le fichier ou non, sinon ferme le flux. Supposons qu'après avoir écrit plusieurs lignes de code, vous perdiez la référence à l'objet. Ensuite, il est admissible à la collecte des ordures. Lorsque la machine virtuelle Java est sur le point de libérer de l'espace de votre objet, elle vérifie simplement si vous avez défini la méthode finalize ou non et invoquez la méthode pour qu'il n'y ait aucun risque du flux ouvert. La méthode de finalisation rend le programme sans risque et plus robuste.