La mise à jour des références n'est pas la seule chose qui nécessite une pause. Les algorithmes standard généralement regroupés sous «balayage de marque» supposent tous que le graphique d'objet entier reste inchangé pendant qu'il est marqué. La gestion correcte des modifications (nouveaux objets créés, références modifiées) nécessite des algorithmes alternatifs plutôt délicats, comme l'algorithme tricolore. Le terme générique est "collecte de déchets simultanée".
Mais oui, la mise à jour des références après compactage nécessite également une pause. Et oui, l'utilisation de l'indirection (par exemple via un ID d'objet persistant et une table de hachage vers des pointeurs réels) peut réduire considérablement la pause. Il pourrait même être possible de rendre cette pièce sans verrou si l'on le souhaite. Il serait toujours aussi délicat de réussir que n'importe quelle concurrence de mémoire partagée de bas niveau, mais il n'y a aucune raison fondamentale pour laquelle cela ne fonctionnerait pas.
Cependant , cela aurait de graves inconvénients. En plus de prendre de l'espace supplémentaire ( au moins deux mots supplémentaires pour tous les objets), cela rend chaque déréférence beaucoup plus chère. Même quelque chose d'aussi simple que d'obtenir un attribut implique désormais une recherche de table de hachage complète. J'estimerais que les performances atteintes sont bien pires que pour le suivi incrémentiel.
Votre approche ne résout pas immédiatement le problème du ramasse-miettes, mais ne le fait monter que d'un niveau. Et à quel prix! Désormais, chaque accès à la mémoire passe par une autre déréférence de pointeur. Nous ne pouvons pas mettre en cache l'emplacement du résultat, car il pourrait avoir été déplacé entre-temps, nous devons toujours passer par l'ID d'objet. Dans la plupart des systèmes, cette indirection n'est pas acceptable et l'arrêt du monde est supposé avoir un coût d'exécution total inférieur.
J'ai dit que votre proposition ne fait que déplacer le problème, pas le résoudre. Le problème concerne la réutilisation des ID d'objet. Les ID d'objet sont maintenant notre équivalent de pointeurs, et il n'y a qu'une quantité finie d'adresses. Il est concevable (en particulier sur un système 32 bits) que pendant la durée de vie de votre programme, plus de INT_MAX objets aient été créés, par exemple dans une boucle comme
Si nous incrémentons simplement l'ID d'objet pour chaque objet, nous manquerons d'ID à un moment donné. Par conséquent, nous devons savoir quels identifiants sont encore utilisés et lesquels sont gratuits pour pouvoir être récupérés. Semble familier? Nous sommes maintenant de retour à la case départ.
la source
Il n'y a pas d'erreur dans votre ligne de pensée, vous venez de décrire quelque chose de très proche du fonctionnement du garbage collector Java d'origine
Donc ça marche, ça a été essayé, et son inefficacité a conduit au développement de systèmes générationnels de marquage et de balayage.
la source
Object.getHashCode()