Autant que je sache, la spécification de la machine virtuelle Java (écrite en anglais) ne mentionne pas le moment précis où un objet (ou une valeur) doit être supprimé, et laisse cela à la mise en œuvre (de même pour R5RS ). Cela nécessite ou suggère un ramasse-miettes, mais laisse les détails à la mise en œuvre. Et de même pour la spécification Java.
N'oubliez pas que les langages de programmation sont des spécifications (de syntaxe , de sémantique , etc.) et non des implémentations logicielles. Un langage comme Java (ou sa machine virtuelle Java) a de nombreuses implémentations. Sa spécification est publiée , téléchargeable (afin que vous puissiez l'étudier) et écrite en anglais. §2.5.3 Le tas de la spécification de la JVM mentionne un ramasse-miettes:
Le stockage de tas pour les objets est récupéré par un système de gestion de stockage automatique (appelé garbage collector); les objets ne sont jamais explicitement désalloués. La machine virtuelle Java n'assume aucun type particulier de système de gestion de stockage automatique
(L’accent est à moi; la finalisation de BTW est mentionnée au § 12.6 de la spécification Java, et un modèle de mémoire est au § 17.4 de la spécification Java)
Donc (en Java) vous ne devriez pas prendre soin quand un objet est supprimé , et vous pouvez coder comme, si cela ne se produit pas (par le raisonnement dans une abstraction où vous ignorez que). Bien sûr, vous devez vous préoccuper de la consommation de mémoire et des objets vivants, ce qui est une question différente . Dans plusieurs cas simples (pensez à un programme "hello world"), vous êtes en mesure de prouver - ou de vous convaincre - que la mémoire allouée est plutôt petite (par exemple, moins d'un gigaoctet), et vous ne vous souciez plus du tout. suppression d' objets individuels . Dans plus de cas, vous pouvez vous convaincre que les objets vivants(ou ceux qui sont joignables, ce qui est plus facile à raisonner que les vivants) ne dépasse jamais une limite raisonnable (et vous vous fiez alors à GC, mais vous vous moquez de savoir quand et comment la collecte des ordures a lieu). Lisez à propos de la complexité de l'espace .
J'imagine que sur plusieurs implémentations de machine virtuelle Java exécutant un programme Java de courte durée, comme celui de hello world, le ramasse-miettes n'est pas déclenché du tout et aucune suppression ne se produit. AFAIU, un tel comportement est conforme aux nombreuses spécifications Java.
La plupart des implémentations JVM utilisent des techniques de copie générationnelles (du moins pour la plupart des objets Java, ceux qui n'utilisent pas la finalisation ou des références faibles ; la finalisation n'est pas garantie et peut être différée. Il s'agit donc d'une fonctionnalité utile que votre code ne devrait pas utiliser. dépend beaucoup de) dans lequel la notion de suppression d’un objet individuel n’a aucun sens (puisqu'un large bloc de mémoire contenant des zones de mémoire pour de nombreux objets, peut-être plusieurs mégaoctets à la fois, est libéré à la fois).
Si la spécification JVM exigeait que chaque objet soit supprimé le plus tôt possible (ou imposait simplement plus de contraintes à la suppression d'objet), les techniques de GC générationnelles efficaces seraient interdites et les concepteurs de Java et de la JVM ont été avisés de l'éviter.
En passant, il est possible qu’une JVM naïve qui ne supprime jamais d’objets et ne libère pas de mémoire se conforme aux spécifications (la lettre, pas l’esprit) et puisse certainement exécuter un problème de bonjour dans la pratique (notez que la plupart les programmes Java minuscules et de courte durée n'allouent probablement pas plus de quelques giga-octets de mémoire). Bien sûr, une telle machine virtuelle ne mérite pas d’être mentionnée et n’est qu’un jouet (comme cette implémentation de malloc
C). Voir le GC Epsilon NoOp pour plus d'informations. Les machines virtuelles Java réelles sont des logiciels très complexes et combinent plusieurs techniques de récupération de place.
En outre, Java n'est pas identique à la machine virtuelle Java et vous avez des implémentations Java qui s'exécutent sans machine virtuelle (par exemple , des compilateurs Java en avance sur le temps , le moteur d'exécution Android ). Dans certains cas (principalement académiques), vous pouvez imaginer (techniques dites de "récupération de place au moment de la compilation") qu’un programme Java n’alloue ni ne supprime au moment de l’exécution (par exemple parce que le compilateur optimiseur a été assez intelligent pour utiliser uniquement pile d'appels et variables automatiques ).
Pourquoi les objets Java ne sont-ils pas supprimés immédiatement après qu'ils ne sont plus référencés?
Parce que les spécifications Java et JVM ne l'exigent pas.
Lisez le manuel du GC pour plus d’informations (et les spécifications de la JVM ). Notez que le fait d'être en vie (ou utile pour les calculs futurs) d'un objet est une propriété de programme entier (non modulaire).
Objective-C privilégie une approche de comptage de références pour la gestion de la mémoire . Et cela a aussi des pièges (par exemple , l'Objective-C programmeur doit se soucier de références circulaires par explicitant références faibles, mais une machine virtuelle Java traite les références circulaires bien dans la pratique sans nécessiter l' attention du programmeur Java).
Il n'y a pas de solution miracle dans la programmation et la conception de langages de programmation (soyez conscient du problème de l' arrêt, car être un objet vivant utile est indécidable en général).
Vous pouvez également lire SICP , Pragmatique sur les langages de programmation , Le Livre du Dragon , Lisp In Small Pieces et les systèmes d’exploitation: Trois pièces faciles . Ils ne concernent pas Java, mais ils vous ouvriront l'esprit et devraient vous aider à comprendre ce que doit faire une machine virtuelle et comment elle pourrait fonctionner (avec d'autres éléments) sur votre ordinateur. Vous pouvez également passer plusieurs mois (ou plusieurs années) dans l' étude du code source complexe existant open source implémentations de la JVM (comme OpenJDK , qui a plusieurs millions de lignes de code source).