Forcer la libération de grande cache d'objet en Java
J'utilise un grand (en millions de dollars) entrées de la table de hachage pour mettre en cache les valeurs nécessaires à un algorithme, la clé est une combinaison de deux objets, comme une longue. Depuis, il ne cesse d'augmenter (en raison des clés dans le changement de carte, de sorte que les anciens ne sont plus nécessaires), il serait agréable d'être en mesure de la force d'essuyer toutes les données qu'elle contient, et de commencer à nouveau au cours de l'exécution, est il possible de le faire efficacement en Java?
Je veux dire libérer la mémoire associée (environ 1-1.5 go de hashmap) et redémarrer à partir de la table de hachage vide..
OriginalL'auteur Jack | 2010-03-09
Vous devez vous connecter pour publier un commentaire.
Vous pouvez appeler
HashMap.clear()
. Qui va supprimer toutes les données. Notez que cela ne fera que jeter toutes les entrées, mais garder l'intérieur de tableau utilisé pour stocker les entrées à la même taille (plutôt que réduit à une capacité initiale). Si vous aussi vous avez besoin pour l'éliminer, le plus simple serait à rejeter l'ensemble de la table de hachage et de la remplacer par une nouvelle instance. Qui bien sûr ne fonctionne que si vous contrôlez qui a un pointeur sur la carte.Que pour récupérer de la mémoire, vous devez laisser le garbage collector de faire son travail.
Sont vos valeurs aussi Long? Dans ce cas, vous souhaiterez peut-être consulter un plus (de mémoire) efficace
la mise en œuvre du générique HashMap, comme le TLongLongHashMap trouvé dans les GNU Trésors de la bibliothèque. Qui doit sauver beaucoup de mémoire.
OriginalL'auteur Thilo
Il sonne comme vous avez besoin d'un WeakHashMap à la place:
Je ne suis pas sûr de savoir comment cela fonctionne avec
Long
que les clés, si. En outre, cela pourrait être d'intérêt:WeakHashMap n'est pas un cache! La compréhension WeakReference et SoftReference
OriginalL'auteur polygenelubricants
Effacer la table de hachage:
Alors la force d'un garbage collector exécuter:
C'est la Javadoc de la page pour l'Exécution.gc().
gc()
explicitement n'est jamais recommandé, mais je peux me tromper.Je pense que c'est une mauvaise pratique de l'appel gc explicitement. Vous devriez laisser que la JVM.
de toute évidence, l'exécution du garbage collector s'arrête, le monde de se déplacer, et ce parce que c'est une mauvaise idée, étant donné que la JVM est généralement plus conscients que vous quand il a besoin de plus de mémoire. Cela mis à part, dans des circonstances exceptionnelles, si le but est de récupérer 1,5 GO de mémoire, j'aimerais lui donner un aller. Surtout depuis qu'il va être appelé dans un très déterministe de la mode (quand la table de hachage est désactivée).
"de toute évidence, l'exécution du garbage collector s'arrête, le monde de se déplacer". Qui n'est pas (toujours) vrai. La plupart de la collecte des ordures peuvent se produire simultanément maintenant. Et il n'y a aucune garantie de ce genre de collection gc() de le faire (le cas échéant). Je pense que sur le courant de la JVM Hotspot, vous devez appeler le gc() trois ou quatre fois dans une ligne de force d'une collection complète. Et encore une fois, pourquoi voulez-vous récupérer de la mémoire immédiatement? La JVM va récupérer pour vous quand vous avez besoin de la mémoire.
la JVM est conscient de lui-même, mais pas les autres processus. Il peut sembler parfaitement bien pour la JVM de prendre jusqu'à 1,5 GO, même si la plupart de ce qui est des ordures, mais qui peut ne pas être acceptable à mon système. Cela étant dit, en disant que la collecte des ordures ne s'arrête pas plus le monde ne sonne pas comme un argument à l'encontre des appels directs à la collecte des déchets. Je suis prêt à croire que c'est une mauvaise pratique, mais pouvez-vous expliquer pourquoi? La plupart des articles que j'ai lu à ce sujet dit que c'était précisément à cause de cette tendance que c'était une mauvaise pratique.
OriginalL'auteur zneak
Pour un mémoire-conscience de cache, vous pouvez utiliser Apache Commons collections, en particulier leur
org.apache.commons.collections.map.ReferenceMap
classe. La Java opération spéciale est une soft de référence. Java fournitWeakHashMap
pour les références faibles, mais la faiblesse des références ne sont pas ce que vous voulez pour un cache. Java ne fournit pas unSoftHashMap
, maisReferenceMap
de Apache Commons peuvent être un substitut viable.Mémoire de sensibilisation de doux références est un peu brut et inflexible. Vous pouvez jouer avec quelques options Java pour en quelque sorte les configurer, en particulier la
-XX:SoftRefLRUPolicyMSPerMB
valeur, qui exprime (en millisecondes) pendant combien de temps doux-référencé valeurs sont gardées en mémoire (quand ils cessent d'être directement accessible). Par exemple, avec cette:puis la JVM va essayer de garder la valeur mise en cache pendant 2,5 secondes de plus que ce qu'il aurait fait avec un
WeakHashMap
.Si doux références ne pas fournir ce que vous recherchez, alors vous aurez à mettre en place votre propre stratégie de cache, et, en effet, rincer la carte manuellement. C'est votre question initiale. Pour le rinçage, vous pouvez utiliser le
clear()
méthode, ou tout simplement de créer un nouveauHashMap
. La différence doit être légère, et vous pouvez même avoir de la difficulté à simplement mesure cette différence.L'alternance entre le "cache complet" et "vider le cache" peut aussi être considéré comme un peu brut, de sorte que vous pourriez maintenir plusieurs cartes. Par exemple, vous maintenir dix cartes. Quand vous regardez pour une valeur mise en cache, vous regardez dans toutes les cartes, mais quand vous avez eu une valeur, vous le mettez dans la première carte. Lorsque vous voulez de chasse, vous vous tournez les cartes: la première carte est la seconde, la seconde devient la troisième, et ainsi de suite, jusqu'à la dixième carte qui est rejetée. Une nouvelle fraîche première carte est créée. Cela devrait ressembler à ceci:
Le code ci-dessus est complètement mises à l'épreuve et doit être renforcée avec des génériques. Cependant, il illustre les principales idées: toutes les cartes sont testées lors de la lecture (
get()
), toutes les nouvelles valeurs d'aller à la première carte, la taille totale est maintenue, et lorsque la taille dépasse une certaine limite, les cartes sont retournées. Notez qu'il est certain d'un traitement spécial lorsqu'une nouvelle valeur est mis pour un clé. Aussi, dans cette version, rien de spécial n'est fait lors de la recherche d'une valeur mise en cache, mais nous avons pu "rajeunir", consulté valeur mise en cache: surget()
, lorsqu'une valeur est trouvé mais pas dans la première carte, il pourrait être déplacé dans la première map. Ainsi, fréquemment consulté les valeurs restent en cache jamais.La taille de la matrice est bien plus petite que la taille collective de la pointe-aux objets. D'ailleurs, si c'est un cache qui vous régulièrement vide, alors, par définition, vous pourrez le remplir à nouveau, et le grand tableau être de retour à un certain point. À l'aide de
clear()
signifie que vous maintenir le réseau autour, mais éviter la réaffectation des par la suite, et aussi d'éviter un certain niveau de ressasser lorsque le tableau interne augmente. Je ne pense pas que cela fait une différence mesurable dans le long terme.OriginalL'auteur Thomas Pornin
Avez-vous pris un coup d'oeil à WeakHashMap?
Oui, je l'ai mentionné ce doute dans mon post trop.
OriginalL'auteur TofuBeer
Si vous avez un peu de mémoire libre, vous pouvez implémenter un timout cache où chaque valeur dans la table de hachage contient votre valeur de type long et un insersion d'horodatage dans millis - alors un thread d'arrière-plan itération sur les valeurs de toutes les X secondes et retirer quelque chose de plus que les X secondes/millis vieux.
Juste mes 2 cents 🙂
OriginalL'auteur simonlord
Au lieu d'utiliser un
HashMap
ou autre carte de mise en œuvre comme un cache, vous pouvez essayer d'utiliser un framework spécialisé dans la mise en cache. Une bien connue cadre de la mise en cache de Java est Ehcache.La mise en cache cadres vous permettent de configurer des stratégies d'expiration en fonction du temps (par exemple, le temps de vivre, le temps de repos) ou d'utilisation (par exemple, moins fréquemment utilisé, le moins récemment utilisé), certains peuvent même vous permettre de spécifier un montant maximum de l'utilisation de la mémoire.
OriginalL'auteur siegi