JavaRush /Blog Java /Random-FR /Cycle de vie des objets

Cycle de vie des objets

Publié dans le groupe Random-FR
Bonjour! Je pense que vous ne serez pas trop surpris si nous vous disons que la taille de la mémoire de votre ordinateur est limitée :) Même un disque dur, qui est plusieurs fois plus gros que la RAM, peut être rempli à pleine capacité avec vos jeux, séries télévisées, séries télévisées préférés, et ainsi de suite. Pour éviter que cela ne se produise, vous devez surveiller l'état actuel de la mémoire et supprimer les fichiers inutiles de votre ordinateur. Qu’est-ce que la programmation Java a à voir avec tout cela ? Direct! Après tout, lorsqu’un objet est créé par la machine Java, de la mémoire lui est allouée. Dans un véritable grand programme, des dizaines et des centaines de milliers d'objets sont créés, chacun ayant sa propre pièce de mémoire allouée. Cycle de vie de l'objet - 1Mais depuis combien de temps pensez-vous que tous ces objets existent ? Est-ce qu'ils « vivent » pendant toute la durée d'exécution de notre programme ? Bien sûr que non. Malgré tous les avantages des objets Java, ils ne sont pas immortels :) Les objets ont leur propre cycle de vie. Aujourd'hui, nous allons faire une petite pause dans l'écriture du code et examiner ce processus :) De plus, c'est très important pour comprendre le fonctionnement du programme et gérer les ressources. Alors, où commence la vie d’un objet ? Comme une personne - dès sa naissance, c'est-à-dire la création.
Cat cat = new Cat();//вот сейчас и начался vital цикл нашего an object Cat!
Tout d'abord, la machine virtuelle Java alloue la quantité de mémoire nécessaire pour créer l'objet. Ensuite, elle crée un lien vers celui-ci, dans notre cas, catpour pouvoir le suivre. Après cela, toutes les variables sont initialisées, le constructeur est appelé, et voilà, notre nouvel objet vit déjà sa propre vie :) La durée de vie des objets est différente, il n'y a pas de chiffres exacts ici. Dans tous les cas, il vit pendant un certain temps à l'intérieur du programme et remplit ses fonctions. Pour être précis, un objet est « vivant » tant qu’il y a des références à lui. Dès qu'il ne reste plus de liens, l'objet « meurt ». Par exemple:
public class Car {

   String model;

   public Car(String model) {
       this.model = model;
   }

   public static void main(String[] args) {
       Car lamborghini  = new Car("Lamborghini Diablo");
       lamborghini = null;

   }

}
Dans la méthode, main()l'objet voiture Lamborghini Diablo cesse d'être vivant déjà sur la deuxième ligne. Il n'y avait qu'un seul lien vers celui-ci, et maintenant ce lien a été attribué null. Puisqu’il n’y a plus de références à la Lamborghini Diablo, elle devient « indésirable ». Il n'est pas nécessaire de réinitialiser le lien :
public class Car {

   String model;

   public Car(String model) {
       this.model = model;
   }

   public static void main(String[] args) {
       Car lamborghini  = new Car("Lamborghini Diablo");

       Car lamborghiniGallardo = new Car("Lamborghini Gallardo");
       lamborghini = lamborghiniGallardo;
   }

}
Ici, nous avons créé un deuxième objet, après quoi nous avons pris la référence lamborghiniet l'avons assignée à ce nouvel objet. Lamborghini GallardoIl y a maintenant deux références pointant vers l'objet, mais Lamborghini Diabloaucune vers l'objet. L’objet Diablodevient donc un déchet. Et à ce moment-là, le mécanisme Java intégré appelé garbage collector, ou en d'autres termes - Garbage Collector, GC, entre en action.
Cycle de vie des objets - 2
Le garbage collector est un mécanisme Java interne chargé de libérer de la mémoire, c'est-à-dire d'en supprimer les objets inutiles. Ce n’est pas pour rien que nous avons choisi une photo avec un robot aspirateur pour le représenter. Après tout, le ramasse-miettes fonctionne à peu près de la même manière : en arrière-plan, il « voyage » à travers votre programme, collecte les ordures et en même temps, vous n'interagissez pratiquement pas avec lui. Son travail consiste à supprimer les objets qui ne sont plus utilisés dans le programme. Ainsi, cela libère de la mémoire dans l’ordinateur pour d’autres objets. Vous souvenez-vous qu'au début de la conférence, nous avons dit que dans la vie ordinaire, vous deviez surveiller l'état de votre ordinateur et supprimer les anciens fichiers ? Ainsi, dans le cas des objets Java, le garbage collector le fait pour vous. Garbage Collector est lancé plusieurs fois au cours du fonctionnement de votre programme : il n'est pas nécessaire de l'appeler spécifiquement ni de lui donner des commandes, bien que cela soit techniquement possible. Plus tard, nous en parlerons davantage et analyserons plus en détail le processus de son travail. Au moment où le garbage collector atteint l'objet, juste avant sa destruction, une méthode spéciale est appelée sur l'objet - finalize(). Il peut être utilisé pour libérer certaines ressources supplémentaires utilisées par l'objet. La méthode finalize()appartient à la classe Object. Autrement dit, avec equals(), hashCode()et toString(), que vous avez déjà rencontrés plus tôt, n'importe quel objet l'a. Sa différence avec les autres méthodes est qu'elle est... comment dire... très capricieuse. A savoir qu’il n’est pas toujours appelé avant de détruire un objet. La programmation est une chose précise. Le programmeur demande à l’ordinateur de faire quelque chose, et l’ordinateur le fait. Vous êtes probablement déjà habitué à ce comportement, et il peut vous être difficile au début d'accepter l'idée : « Avant que les objets ne soient détruits, la méthode finalize()de classe est appelée Object. Ou on ne l'appelle pas. Si nous avons de la chance !" Cependant, c'est vrai. La machine Java détermine elle-même si elle doit appeler finalize()ou non la méthode dans chaque cas spécifique. Par exemple, essayons d'exécuter le code suivant à des fins d'expérimentation :
public class Cat {

   private String name;

   public Cat(String name) {
       this.name = name;
   }

   public Cat() {
   }

   public static void main(String[] args) throws Throwable {

       for (int i = 0 ; i < 1000000; i++) {

           Cat cat = new Cat();
           cat = null;//вот здесь первый an object становится доступен сборщику мусора
       }
   }

   @Override
   protected void finalize() throws Throwable {
       System.out.println("Объект Cat уничтожен!");
   }
}
Nous créons un objet Catet dans la ligne de code suivante, nous réinitialisons la seule référence à celui-ci. Et ainsi – un million de fois. Nous avons explicitement remplacé la méthode finalize()et elle doit imprimer la chaîne sur la console un million de fois, à chaque fois avant de détruire l'objet Cat. Mais non! Pour être précis, il n’a fonctionné que 37 346 fois sur mon ordinateur ! Autrement dit, la machine Java que j'ai installée n'a décidé d'appeler une méthode que dans 1 cas sur 27 finalize()- dans d'autres cas, le garbage collection s'est déroulé sans cela. Essayez d'exécuter ce code vous-même : le résultat sera très probablement différent. Comme vous pouvez le constater, finalize()il est difficile de qualifier cela de partenaire fiable :) Alors, un petit conseil pour l'avenir : il ne faut pas se fier à la méthode finalize()en cas de libération de certaines ressources critiques. Peut-être que la JVM l'appellera, peut-être pas. Qui sait? Si pendant sa durée de vie votre objet a occupé des ressources très importantes pour les performances, par exemple s'il a gardé une connexion ouverte à la base de données, il est préférable de créer une méthode spéciale dans votre classe pour les libérer et de l'appeler explicitement lorsque l'objet est ne sont plus nécessaires. De cette façon, vous saurez avec certitude que les performances de votre programme n’en souffriront pas. Au tout début, nous avons dit que la gestion de la mémoire et la suppression des déchets étaient très importantes, et c'est vrai. Une gestion inappropriée des ressources et un manque de compréhension du processus d'assemblage d'objets inutiles peuvent entraîner des fuites de mémoire. C’est l’une des erreurs de programmation les plus connues. Un code mal écrit par le programmeur peut entraîner l'allocation d'une nouvelle mémoire à chaque fois pour les objets nouvellement créés, tandis que les anciens objets inutiles ne peuvent pas être supprimés par le ramasse-miettes. Puisque nous avons fait une analogie avec un robot aspirateur, imaginez ce qui se passerait si, avant de démarrer le robot, vous éparpilliez des chaussettes dans la maison, cassiez un vase en verre et laissiez un ensemble Lego démonté sur le sol. Le robot, bien sûr, essaiera de faire quelque chose, mais à un moment donné, il restera bloqué.
Cycle de vie des objets - 3
Pour qu'il fonctionne correctement, vous devez garder le sol en bon état et en retirer tout ce que l'aspirateur ne peut pas manipuler. Le garbage collector fonctionne sur le même principe. S'il reste de nombreux objets dans le programme qu'il ne peut pas collecter (comme une chaussette ou un Lego pour un robot aspirateur), à un moment donné, la mémoire s'épuisera. Et non seulement le programme que vous avez écrit se bloquera, mais également tous les autres programmes exécutés sur l'ordinateur à ce moment-là. Il n'y aura pas non plus assez de mémoire pour eux. Voici à quoi ressemblent le cycle de vie des objets et le garbage collector en Java. Il n'est pas nécessaire de mémoriser cela : il suffit de comprendre le principe de fonctionnement. Dans la prochaine conférence, nous parlerons de ces processus plus en détail, mais pour l'instant vous pouvez revenir à la résolution des problèmes JavaRush :) Bonne chance !
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION