6
votes

Références douces (non: faibles) en C ++ - est-ce possible? Y a-t-il une mise en œuvre?

in c ++ J'utilise boost :: Shared_ptr et boost :: faible_ptr pour supprimer automatiquement des objets qui ne sont plus nécessaires. Je connais ces travaux avec le comptage de référence.

En Java, la mémoire est gérée par un collecteur à ordures, qui compte les références d'objet intégrées comme fort , faim comme faible et softreference comme quelque chose entre les deux (peut être collecté par le GC, mais peut aussi survivre au GC), ce qui est vraiment pratique pour la mise en cache des objets pendant un certain temps, Mais les jeter dès que la mémoire libre devient faible.

Alors maintenant je suis de retour en C ++ et me manque le confort d'avoir des références douces. Je me demande si le référencement doux est réalisable avec le comptage de référence du tout. Lorsque la dernière référence forte à un objet est effacée et il reste une référence douce , quand serait-elle supprimée après tout? Je pouvais penser à certains schémas, mais aucun d'entre eux ne nous semble intelligent.

Juste au cas où il y a une sémantique appropriée pour les références douces avec le comptage de référence, je me demande si cela a déjà été mis en œuvre, peut-être d'une manière même compatible avec Boost :: Shared_ptr (ou le C ++ Tr1 équivalent std :: partagé_ptr d'ici la matière).

Si la réponse aux deux questions est non, quelles sont les alternatives dans un scénario de mise en cache d'objet?

EDIT: Bien sûr, je parle d'une situation lorsque la mise en cache est réellement utile, car les objets sont coûteux à construire (penser à plusieurs accès à une base de données et aux requêtes d'un réseau), mais il y en a trop de Gardez-les tous pour toujours.


11 commentaires

Qu'est-ce que sur la terre est une référence douce quand elle est à la maison?


@Deadmg: en.wikipedia.org/wiki/soft_reference


@Deadmg: Que voulez-vous dire? Je ne suis pas un organisateur anglais natif, donc si ce commentaire implique une sorte d'humour, je suppose que je ne l'obtiens pas. Si c'est une vraie question, eh bien, je ne l'obtiens pas non plus.


Je ne comprends pas non plus - ce doit être une sorte de référence.


Une référence douce n'est qu'une note de faible référence. Comme le lien que j'ai souligné des spectacles. Dans la JVM, les algorithmes de collecte de la mémoire vont d'abord essayer de collecter des ordures. À défaut qu'ils collectent des références faibles. Échouer qu'ils collectent des références douces. Omettre qu'ils vomissent.


"Quand c'est à la maison" est une phrase signifiant ... er ... pas vraiment vraiment. "Quoi de la terre est une référence douce quand elle est à la maison?" signifie "quoi (sur la Terre) est une référence douce?"


@Brian Hooper: Merci, c'était exactement l'information que j'avais manquante :)


@Just: Si vous répondiez à mon commentaire, c'était une blague, bien que une faiblesse.


@AMNON: C'était une douce, pas une faiblesse.


Désolé pour le bowvote, je l'ai nié avec un uppote. Je clique dessus au hasard sur l'écran lorsque je frappe la flèche vers le bas :-(


@ Dragonamer5788 pas de problème. Vous pouvez normalement reprendre un bowvote en cliquant à nouveau sur la flèche vers le bas, alors votre vote devient à nouveau neutre. Je peux voir qu'il n'existe actuellement aucun bowvote sur cette question (vous avez besoin de 1000 réputation pour montrer les chiffres totaux de vote de haut en bas).


5 Réponses :


-2
votes

Non, il n'y a pas de telle chose en C ++. Il ne devrait pas non plus y avoir. Chaque objet constitue un objectif important. Si ce n'est pas le cas, pourquoi l'avez-vous toujours? Garder les objets autour de cette manière est une fuite de mémoire. Si vous avez besoin d'un objet, vous en avez besoin. Si vous ne le faites pas, détruisez-le. Il n'y a pas d'entre eux entre l'intérêt utile et inutile, soit il sert un but ou cela ne le fait pas.

Si vous êtes désespéré, il n'est pas impossible d'écrire votre propre collecteur à ordures et de mettre en œuvre une telle chose vous-même. Mais je recommanderais de les avoir besoin ou de les utiliser du tout.

EDIT: Dans la mise en cache d'objet, les personnes utilisent normalement des caches LRU. Lorsque vous avez un cache Miss, la référence à l'objet moins récemment utilisé est détruite (si le cache est plein), le nouvel objet est créé et mis en tant que le plus récent utilisé, et tous les autres sont déplacés. Toutefois, vous devez généralement récupérer des éléments du disque avant d'avoir besoin d'une stratégie de mise en cache en C ++. Le coût de la création de la plupart des objets n'est tout simplement pas si génial.


7 commentaires

Je ne suis pas sûr de voir comment une référence douce, comme le décrit Brian, est une fuite de mémoire alors qu'un cache LRU n'est pas. Soit vous avez besoin de l'objet, soit vous ne le faites pas.


En résonenant votre édition, j'ai également édité ma réponse. J'ai oublié de mentionner que les objets peuvent être plutôt coslty à créer. La stratégie la moins récemment utilisée est en fait une bonne idée. Quoi qu'il en soit, je me demande si je dois mettre cela manuellement dans la mise en œuvre d'un objet en cache-mananging, ou s'il y a une fonctionnalité similaire qui peut être mise en quelque chose comme une référence faible.


@Dennis: Un LRU a une taille fixe. Il peut être nettoyé. Il est contrôlé par l'objet propriétaire. Les références douces sont incontrôlées. Si vous implémentez un LRU, vous avez le contrôle de cette mémoire. Si vous utilisez des références douces, tout le monde pourrait utiliser une référence douce. Les caches LRU sont clairement définies et possédées. Les références douces sont un gaggle de tout le monde.


@Brian: la langue elle-même n'a pas de fonctionnalité similaire. La seule raison pour laquelle il existe en Java est que vous avez déjà un collecteur à ordures, cela peut surgir. Sans GC, quelqu'un d'autre doit prendre la décision de détruire l'objet référencé. Et puis il pourrait aussi bien être mis en œuvre dans une bibliothèque tierce partie. Il n'y a pas de "bonne réponse" qui pourrait être incorporée dans la langue elle-même.


"Gaggle de tout le monde" = Cet objet vaut la peine d'avoir s'il y a de l'espace pour cela, pas s'il n'y a pas. "Cache LRU" = J'utiliserai exactement 1 Go de mémoire, et je m'en fiche si cela signifie que vos autres applications ne s'exécuteront pas. Sur un système d'exploitation de bureau, le manque de mémoire est un problème rare et ne nécessite pas beaucoup de technique de la part des applications. "S'il y a de l'espace" est essentiellement toujours vrai. Sur les systèmes contraints, il peut être vraiment important que les applications coopèrent sur une utilisation de la mémoire et des références douces sont un outil (relativement émoussé) pour le faire.


@Steve: J'ai déjà exprimé mon opinion que "cet objet vaut la peine d'avoir si il y a de l'espace pour cela et non s'il n'y a pas" est assez défectueux.


C'est fou. L'utilisation de CACEHS de taille fixe n'est pas aussi efficace que l'utilisation de caches dynamiques qui échouent sur des facteurs de ressources extérieurs tels que la mémoire disponible.



1
votes

Vous pouvez implémenter votre propre cache LRU et un nouveau Smart_Pointer associé à un tel cache. Je ne pense pas qu'une telle structure existe dans Boost ou Standard C ++ (hors de la tête de ma tête de toute façon). Si vous faites une application Web ou quelque chose ... vous pouvez utiliser libmemcached, qui est l'interface C à Memcached.

J'ai du mal à penser à une situation où un tel objet serait si coûteux de construire / détruire ... alors qu'il serait bon marché de réinitialiser ... qu'un cache de LRU deviendrait utile. Mais si vous en avez vraiment besoin d'un, vous avez les outils nécessaires pour le construire.


0 commentaires

7
votes

Comme d'autres ont souligné, vous pouvez trouver Référencé les pointeurs comptés (et leur assistant faible Contreparts ) Dans la bibliothèque Boost, mais ce qui manque de la la référence douce est une certaine prise de conscience des contraintes de mémoire de l'environnement d'exécution. En Java, par exemple, un softreference n'est pas matériellement différent d'un faibles dans ses capacités; plutôt, c'est Le contrat de la manière dont le temps d'exécution sera conservez ou expulsez les deux types de références face à la pression de mémoire diffère.

Pour imiter ce comportement en C ++, vous devez construire un cache de référence conscient de la mémoire qui détenait des références fortes sur des objets que le reste de votre application conserve faiblement < / em>. Lorsque le cache a déterminé que l'application se grattait son plafond d'utilisation de la mémoire - ou tout autre critère de contrainte - il publierait les bonnes références, ce qui rendait les objets de "collection" (atteignant le nombre de référence zéro) et permettant aux faibles références utilisées pour plus tard détecter l'invalidation.


2 commentaires

Permettez-moi de demander ... n'est-ce pas quelque peu ce que fait un collecteur à ordures? Récupérer la mémoire lorsque les programmes en ont besoin?


Oui, un collecteur d'ordures peut rendre la mémoire préalablement attribuée à des objets sans plus longue accessibles pour les nouveaux objets, avec impatience ou uniquement sur demande. La question ne concernait pas comment intégrer un collecteur à ordures, mais plutôt si on pouvait imiter la sensibilisation à la pression d'un collecteur. En utilisant des pointeurs forts et faibles en C ++, un type de collection de déchets, mais il n'ya aucun moyen d'exprimer un désir de "épingler un objet seulement jusqu'à ce que nous ayons besoin de plus de mémoire". Les pointeurs forts pivent inconditionnellement et les pointeurs faibles ne font pas partie du tout. Les pointeurs doux existent entre ces extrêmes.



2
votes

Si vous voulez vraiment reproduire ce comportement, vous pouvez utiliser un collecteur de déchets (comme celui-ci: http://www.hpl.hp.com/personal/hans_boehm/gc/ ) et utilisez-le pour prendre soin de votre objet ou un sous-ensemble d'entre eux, où utiliser Softreferences serait utile.

Mais je préférerais aller pour une solution plus originaire de C ++ que de reproduire Java Bahavior - mais rien ne vous empêche de le faire.


0 commentaires