La mise en cache à l'aide de références faibles peut ralentir considérablement votre application si elle est reconstruite à la demande, par ex. dans getters:
public Object getSomethingExpensiveToFind() {
if(cache.contains(EXPENSIVE_OBJ_KEY)) {
return cache.get(EXPENSIVE_OBJ_KEY);
}
Object sth = obtainSomethingExpensiveToFind(); // computationally expensive
cache.put(EXPENSIVE_OBJ_KEY, sth);
return sth;
}
imaginer ce scénario:
1) application est faible sur la mémoire
2) GC nettoie les références faibles, ce cache est effacé trop
3) application continue , beaucoup de méthodes comme getSomethingExpensiveToFind() sont invoquées et reconstruire le cache
4) l'application est à nouveau faible en mémoire
5) GC nettoie l'usure des références, efface le cache
6) l'application continue, beaucoup de méthodes comme getSomethingExpensiveToFind() sont invoquées et reconstruire le cache à nouveau
7) et ainsi de suite ...
Je suis tombé sur un tel problème - l'application a été interrompue par GC très souvent et il a complètement détruit tout le point de mise en cache. En d'autres termes, si elles sont mal gérées, les références faibles peuvent ralentir votre application.
Évidemment, cela dépendra de la mise en œuvre du JDK, Sun vs IBM vs JRockit, etc. –
Début d'une réponse dans un article de [Goetz] (http://www.ibm.com/developerworks/java/library/j- jtp01246/index.html): * A chaque garbage collection, une liste d'objets de référence doit être construite, et chaque référence doit être traitée de manière appropriée, ce qui ajoute du temps de référence par référence à chaque collection, que le référent soit collecté ou non. ce temps. Les objets de référence eux-mêmes sont sujets à la collecte des ordures et peuvent être collectés avant le référent, auquel cas ils ne sont pas mis en file d'attente. * – assylias