Je souhaite implémenter un pool d'objets réutilisable. De plus, je ne veux pas avoir d'API qui remet l'objet en pool quand ce n'est pas nécessaire. Je veux utiliser garbage collector pour m'informer qu'il va supprimer l'objet car il n'a pas de références, afin que je puisse arrêter l'objet d'être ramassé et le remettre dans la piscine. Pourquoi ne pas garder une référence à l'objet, afin qu'il ne soit pas marqué pour gc?Est-il possible d'empêcher le ramassage des ordures au moment où il a été appelé?
Répondre
En réponse à votre question sur la façon dont le GC sait n'est pas utilisé plus:
Une façon de collecte des ordures garde un compte de référence. Lorsque le nombre de références atteint 0, l'objet n'est plus référencé et peut être récupéré. Ce n'est pas ainsi que .NET l'implémente (voir Garbage Collection) mais il pourrait être utile de mieux comprendre le principe. Comment je le comprends, vous avez besoin d'un groupe d'objets qui ont déjà été instanciés, et que vous pouvez simplement distribuer et collecter. Fondamentalement, vous voulez mettre en œuvre la gestion de la mémoire sur le GC. La seule raison que je peux voir pour vouloir faire ceci est que créer une nouvelle instance de l'objet et la rendre utilisable (l'initialisation) prend trop de temps.
Dans tous les cas, vous pouvez essayer l'approche non gérée traditionnelle:
Stack pool = new Stack();
// Initialize a few MyObjects
pool.Push(new MyObject());
// Get an instance of the object from the pool
MyObject obj = (MyObject)pool.Pop();
// Use the object
obj.Foo();
// When you are finished clean up
pool.Push(obj);
obj = null;
Si votre classe Pool est simplement une liste d'objets que vous voulez avoir dans, ils ne seront jamais les déchets ramassés puisque vous avez toujours une référence aux objets de votre piscine.
Mais alors, comment le pool sait-il si un objet est utilisé ou non? –
Vous allez trouver que c'est relativement irréaliste. Il n'y a aucun moyen que le GC vous avertisse des objets qu'il est sur le point de détruire. Il semble que vous essayez de gérer votre propre espace de mémoire, ce qui n'est pas une tâche pour laquelle C# est orienté. Certes, vous pouvez le faire en utilisant un système de pool et un nombre de références afin que vous sachiez quand vos objets ne sont pas référencés par quiconque. Cela semble très risqué, cependant.
Je ne pense pas qu'il existe un moyen réaliste de garder une référence compte vous-même. –
Je pense qu'il est théoriquement possible de mettre en œuvre un schéma de recyclage utilisant des références faibles C#. L'idée est de construire des proxys pour vos objets gérés et d'émettre ces proxys lorsqu'un client demande un objet à partir du pool. Le pool contient une référence à l'objet réel et une référence faible à l'objet proxy. (Et le proxy a une référence directe à l'objet réel.)
Lorsque l'application supprime une référence à un objet proxy, elle sera (finalement) récupérée et, plus tard, la référence faible du pool sera cassé. Plus tard encore, le pool remarque que la référence faible contient une valeur nulle et peut ensuite émettre un nouveau proxy en toute sécurité, créer une nouvelle référence faible et l'envoyer à l'application.
En pratique, c'est vraiment une mauvaise idée. Pour commencer, les références faibles sont susceptibles d'être coûteuses pour le GC, et cela peut prendre plusieurs cycles du GC pour que les références faibles soient brisées. Et ajoutez l'espace utilisé par le pool et les proxies, ainsi que le coût de performance des opérations via des proxys. Il est fort probable que la somme de ces coûts l'emportera sur les avantages du recyclage des objets à l'aide d'un pool d'objets.
Je ne pense pas que vous obtiendrez une réponse satisfaisante pour un pool qui retournera par magie des objets inutilisés, sinon tout le monde le ferait. Java a un ReferenceQueue sur lequel les objets collectés par le garbage sont placés, mais même là je ne recommanderais pas selon le comportement du GC.
Si vous voulez éviter d'avoir à relâcher explicitement l'objet du pool, avez-vous pensé à utiliser une fonction callback/delegate? L'API accepterait un délégué qui fournirait l'objet, et l'application pourrait utiliser l'objet dans le délégué. Quand il se termine, le nettoyage est garanti. (EDIT: je veux dire qu'il est garanti de retourner à la piscine).
class Pool
{
public delegate void UseResource(Object object);
public void GetObject(UseResource del)
{
Object o = null;
try {
o = getFromPool();
del(o)
} finally {
if (o != null) returnToPool(o);
}
}
}
Je ne comprends pas vraiment ce que vous voulez dire avec le nettoyage est garanti. Si vous voulez dire que l'objet est retourné dans le pool, alors, bien sûr, il n'y a aucune raison pour que l'objet ne soit pas référé à l'extérieur. –
Oui, je voulais dire qu'il a été retourné à la piscine. J'ai terminé cette phrase un peu vite sans réfléchir. Le contrat de l'API doit être que vous ne devez utiliser que l'objet fourni dans le délégué - si vous le gardiez, le comportement ne serait pas défini, donc il pourrait ne pas être approprié pour certaines utilisations. C'est probablement pourquoi la plupart des API ont explicitement libéré :) – Nick
- 1. Django: Récupérer threads actifs au moment où le dernier poste a été créé
- 2. Détermination du moment où le contrôle IE activex a été repeint
- 3. Quand ramasser les ordures
- 4. Rhino Mocks: Comment vérifier qu'un constructeur a été appelé
- 5. Servlet Exception - getOutputStream() a déjà été appelé pour cette réponse
- 6. Collecte des ordures dans le rendement Méthodes
- 7. Comment mon javascript peut-il déterminer s'il a été appelé par WScript ou un navigateur?
- 8. Est-il possible de déterminer si l'assembly a été chargé dans un service Web?
- 9. Est-il possible de charger un assistant Rails au moment de l'exécution?
- 10. Quel a été le plus long moment pour réparer un bug?
- 11. enregistrer le périphérique au moment de l'exécution
- 12. Est-il possible de remplacer un attribut qui a été appliqué au niveau du contrôleur sur une méthode spécifique?
- 13. Rhino Mocks Assertion propriété Setter a été appelé avec le type d'objet correct
- 14. L'événement MouseUp a-t-il été interrompu?
- 15. Est-il possible de détecter si un moteur de recherche Opensearch spécifique a été ajouté au navigateur?
- 16. asp MVC: Est-il possible de déterminer comment une méthode de contrôleur a été appelée?
- 17. Pourquoi IExpando.AddMethod n'a pas été appelé?
- 18. Vérifier si le fichier a été créé au cours des X dernières heures
- 19. Sql Server L'accès au Filestream a été refusé.
- 20. Quel objet a été cliqué lorsqu'un événement a été déclenché?
- 21. Est-il possible d'écrire des extensions au débogueur de Delphi?
- 22. Est-il possible de détecter quel bouton asp: a été cliqué dans l'événement Page_init?
- 23. C# DataContractJsonSerializer à l'exclusion des champs au moment de l'exécution
- 24. Créer des paramètres ODBC au moment de l'installation?
- 25. Comment puis-je savoir si "abort()" a été appelé sur un XMLHTTPRequest
- 26. Collecte des ordures ménagères pour ValueType enrubanneuse
- 27. Comment puis-je tester que JavaScript a été appelé avec les bons arguments dans GWT?
- 28. C# Assemblage introuvable au moment de l'exécution
- 29. Quand et où a été inventé le terme «analyse la plus vexante»?
- 30. Où vérifiez-vous si un correctif de Microsoft a été appliqué à des service packs?
Mais alors, comment le pool sait-il si un objet est utilisé ou non? –
L'objet est mentionné, pas "en cours d'utilisation". Si ce n'est plus fait référence il peut être ramasser pour gc –
Vous manquez mon point. Un pool d'objets est un mécanisme permettant de suivre les objets qui ne sont pas utilisés par l'application, puis de les distribuer à la demande. Si le pool n'a aucun moyen de dire que l'application n'utilise plus un objet donné, il ne peut pas le distribuer en toute sécurité. –