Je sais qu'il y a un WeakHashMap
dans Java.util
, mais depuis qu'il utilise WeakReference
s pour tout, ce qui est uniquement référencé par ce type Map
, des objets référencés seront perdus au cycle de GC suivant. Il est donc presque inutile si vous souhaitez mettre en cache des données aléatoires, qui est très susceptible d'être demandée à nouveau sans être liée au reste du temps. La meilleure solution serait une carte qui utilise plutôt SoftReference
s, mais je ne l'ai pas trouvée dans le Java RT.
Modifier (août 2012):
Il s'avère que la meilleure solution est probablement Guava 13.0's Cache
classes, expliquée sur Wiki de Guava - C'est ce que je vais utiliser. Il supporte même la construction d'un SoftHashMap
(voir CacheBuilder.newBuilder().softKeys()
), mais ce n'est probablement pas ce que vous voulez, comme Java Expert Jeremy Manson explique (ci-dessous " ll trouver le lien).
Pas que Je sache (novembre 2008), mais vous trouverez une implémentation de SoftHashMap
sur le net.
Comme celui-ci: SoftHashMap
ou celui-ci .
Modifier (novembre 2009)
AS Matthias mentionne dans les commentaires, le Google Guava MapMaker Utilise Softreferences:
A
ConcurrentMap
constructeur, fournissant une combinaison de ces fonctionnalités:
- clés douces ou faibles,
- valeurs douces ou faibles,
- expiration chronométrée, et
- calcul à la demande des valeurs.
Comme mentionné dans Ce fil , un autre candidat JSR166Y:
jsr166y.concurrentRerenceFerenceHashMap
Il fournit une alternative carte de référence simultanée à la mise en œuvre de Google (qui repose sur un thread de fond aux entrées d'expulsion)
Edit (août 2012)
L'implémentation Google utilise un fil d'arrière-plan uniquement lorsque l'expiration chronométrée des entrées est demandée. En particulier, il utilise simplement Java.util.Timer
, qui n'est pas si intrusif comme ayant un fil de fond séparé.
Jeremy Manson recommande, pour n'importe quel cache, à l'aide de cette fonctionnalité pour éviter les dangers de SofTreference: http://jeremymanson.blogspot.de/2009/07/how-hotspot-decides-a-clear_07.html
Il y a une autre mise en œuvre de Apache Commons , nommément org.apache.commons.collections.map.referencemap ; Il ne supporte pas le retrait chronométré, mais il prend en charge le choix de savoir si les clés doivent être comparées par l'identité ou par l'égalité. De plus, cette mise en œuvre n'est pas concurrente - elle peut être faite synchronisée, mais cela fonctionne moins bien sous des accès à partir de threads multiples.
Je connais deux bibliothèques qui offrent une implémentation de SoftHashMap:
Apache Commons : org.apache.commons.collections.map.referencemap
collections Google : com.google.common.collect.Referencemap
Il existe un exemple de mise en œuvre dans 98 problème de Java Bulletin d'information
Avez-vous envisagé d'utiliser un LRUMAP au lieu d'un hashmap souple? Vous obtenez plus de contrôle sur ce qui est stocké (ou au moins, combien).
Si vous souhaitez mettre en œuvre une cache Softreferences est définitivement une meilleure idée que les références faibles, mais il met toute votre politique d'élimination du cache entre les mains du collecteur des ordures. Ce qui n'est probablement pas ce que vous voulez.
Si la politique d'élimination du cache est importante, vous devrez le faire sur votre propre probabilité en utilisant des références régulières. Cependant, vous allez devoir décider quand éjecter des articles et pour éjecter. Si vous ne voulez que perdre des choses lorsque vous manquez d'espace de tas, vous pouvez interroger des espaces de démarrage disponibles via:
Runtime.getRuntime().getFreeMemory();
Ensuite, une fois que la mémoire libre tombe en dessous d'une certaine quantité, vous pouvez démarrer des éléments de dépose. Ou vous pouvez simplement implémenter une taille maximale pour le cache et utiliser cela pour décider quand déposer des choses.
voici un Cache LR J'ai conçu avec O(1) Insertion, Deletion et temps de recherche, comportant un nombre maximum configurable d'éléments. Si vous voulez un cache, ceci est va être une meilleure solution imho qu'un SoftHashMap.
Les softreférences sont un excellent moyen de créer un cache griffable. La solution idéale serait donc d'utiliser une softhashmap avec un cache de taille fixe régulière. Demandez à tous les insertions dans le cache d'entrer dans le cache fixe et de la carte de hachage logicielle, puis de référencer quelque chose, voyez simplement si c'est dans le hayonnage mou (et mettez à jour le temps de référence dans le cache). Ainsi, tous vos articles les plus importants (selon la stratégie choisie LRU, MFU, ...) ne seront jamais supprimés car ils sont désignés dans le cache, mais vous serez également conserver à plus de choses (sans contrôle de politique). comme il y a suffisamment de mémoire.