6
votes

Pourquoi la collecte Raii et les ordures sont-elles mutuellement exclusives?

Bien que je pense que je comprends que je comprenne le problème du problème (c'est-à-dire une bonne piste GC objets , pas Portée ), je ne sais pas assez sur le sujet de convaincre d'autres.

Pouvez-vous me donner une explication sur pourquoi il n'y a pas de langues collectées à la poubelle avec destructeurs déterministes?


1 commentaires

-1 La question est fausse. Il y a des ordures collectées avec des destructeurs déterministes, par ex. Idisposable sur .NET fournit une destruction déterministe pour C #, vb.net et f #.


3 Réponses :


0
votes

de Wikipedia , après avoir noté que les collectionneurs de déchets tracés sont les plus Type commun:

La collecte des ordures de traçage n'est pas déterministe. Un objet qui devient éligible à la collecte des ordures généralement être nettoyé éventuellement, mais Il n'y a pas de garantie quand (ou même Si) cela se produira.

Par conséquent, s'appuyer sur Raii pourrait conduire à la ressource étant éliminée trop tard.

En conséquence, par exemple, Java a une ligne directrice pour "éviter les finaliseurs" (point 6 de "Java efficace" de Josua Bloch). "Rien de temps critique ne devrait jamais être fait dans un finisseur."


4 commentaires

FWIW La page Wikipedia sur la collecte des ordures est généralement fausse, y compris cette section.


@Jonharrop - toute critique spécifique de cette réponse est la bienvenue.


Il est clair que l'action d'un simple algorithme de GC est complètement déterministe dans une seule application filetée. Il peut être difficile ou non de prédire, mais mon système au moins a un appel de collecte explicite () qui exécute le GC et dirigera les finaliseurs. Le déterminisme n'est perdu que dans les applications multi-threads, qui peuvent avoir la limite ou le non-déterminisme sans engagement de toute façon (selon le système et l'application), il n'est donc pas clair que même dans ce cas, un GC fait des choses pires qu'elles ne le sont déjà.


@Yttrill: Exactement, mais je pense que le problème sous-jacent est qu'aucune des personnes qui utilisent le mot "déterminisme" dans le contexte de la collecte des ordures comprennent ce que ce mot signifie réellement.



0
votes

Le collecteur des ordures ne peut pas fonctionner tout le temps (refcounting se rapproche, mais ne compte généralement pas comme collection à la poubelle), donc cela n'essaie même pas. Il est assez pratique. Par conséquent, il existe un délai inévitable entre un objet devenant inaccessible (par exemple, car la seule référence est hors de portée) et le GC la collecte, éventuellement licenciée. Ce délai n'est pas déterministe ... à moins que (et puis, la destruction déterministe dans le sens le plus stricte du mot est possible, bien que toujours impraticable) force le GC dans un calendrier déterministe - mais cela devient assez proche de "GC exécutant tout le temps" , qui est toujours incroyablement impraticable.

SO GC et le nettoyage déterministe sont mutuellement exclusifs car le GC fait tout le nettoyage et il ne peut pas se permettre de déterminer, mais doit compter sur la maximisation de son efficacité.


0 commentaires

3
votes

Ils ne sont pas mutuellement exclusifs. N'hésitez pas à utiliser C ++ avec Libgc (collecteur BoehM-Reiser-Detlefs). Vous pouvez toujours utiliser Raii, des pointeurs intelligents et une suppression manuelle, mais avec le GC en cours d'exécution, vous pouvez également «oublier» de supprimer des objets.

La réponse de @ Andy concernant les ressources étant éliminées trop tard, manque le point important: ce n'est pas le retard de libération de ressources qui sont cruciales sémantiquement, mais plutôt l'ordre de libération.

La raison pour laquelle GC a tendance à ne pas ordonner la libération, c'est qu'il nécessiterait un tri topologique sur les exigences de commande (dépendances) et c'est un algorithme coûteux.

Néanmoins, OCAML GC a une installation intéressante où vous pouvez attacher un finaliste à un objet. Si l'objet devient inaccessible, le finaliser est exécuté, mais l'objet n'est pas supprimé (car le finaliser pourrait le rendre accessible à nouveau: dans ce cas, vous pouvez même attacher un autre finaliste). Ces finaliseurs peuvent fournir un certain contrôle sur la commande.


2 commentaires

L'ordre de libération peut être important. Mais un délai indéfini pour libérer et une éventuelle incapacité totale de libération, peut également être importante. Ce n'est pas non plus-ou, c'est à la fois - et.


Un délai non défini à la libération peut en effet être important, cela inclut la libération de la mémoire! Question de performance. Mais ce n'est pas pertinent sémantiquement. L'échec complet de la libération est cependant important, mais cela ne peut pas se produire si le GC est exécuté au point de résiliation. Pour certaines ressources telles que les poignées de fichier sur UNIX, on a tendance à ne pas exécuter le GC sur la terminaison, car le système d'exploitation publiera les ressources de toute façon. Les conseils généraux utilisant un GC sont n'utilisent pas RAII pour des ressources critiques, libération sous contrôle du programme. Cependant, ce n'est pas clair ce que cela signifie avec une évaluation paresseuse, par exemple dans Haskell.