2010-03-16 15 views
1

Mon code fait ce qui suit (comme un exemple, et la raison pour laquelle je spécifier le chemin du paquet à java.lang.ref.SoftReference est de noter que ce n'est pas moi-même :-) de implementaiton:Java: des problèmes/côtés négatifs de la conservation de SoftReference à ArrayList dans HttpSession?

... 
List<String> someData = new ArrayList<String>(); 
someData.add("Value1"); 
someData.add("Value2"); 
... 
java.lang.ref.SoftReference softRef = new SoftReference(someData); 
... 
HttpSession session = request.getSession(true); 
session.setAttribute("mySoftRefData", softRef); 
... 

et plus tard:

... 
java.lang.ref.SoftReference softRef = session.getAttribute("mySoftRefData"); 
if (softRef != null && softRef.get() != null) { 
    List<String> someData = (List<String>)softRef.get(); 
    // do something with it. 
} 
... 

Des inconvénients? Ce que je ne vois pas? Je vous remercie!

+0

Les sessions sont parfois sérialisées. Que fait un SoftReference dans ce cas? – Thilo

Répondre

1

L'inconvénient évident est que la liste peut disparaître de façon imprévisible. Comme la session est récupérée après son expiration, je ne vois pas vraiment de cas d'utilisation pour SoftReference. Si la liste devient considérablement grande (au moins assez pour justifier l'utilisation d'un SoftReference), je suggère plutôt un stockage différent (DB, fichiers temporaires).

+0

Je travaille avec une application qui (dans 4 serveurs gérés) prend environ 5G dans les données de session aux heures de pointe, ce qui ralentit considérablement. La plupart de ces données sont mises en cache, et peuvent être supprimées en toute sécurité - si seulement les développeurs se sont souciés ... –

+0

@Vladimir: Alors il appartient plutôt à la demande ou peut-être la portée de l'application. Si réellement dans la portée de l'application, utilisez des frameworks de cache Java comme Ehcache ou Terracotta. – BalusC

+0

Pas du tout. Ce sont toutes les données de l'utilisateur de la banque. C'est juste le backend (HP NonStop) est tellement occupé qu'il est préférable de garder tous les résultats de la requête en mémoire - au cas où (assez souvent) lorsque les mêmes données sont nécessaires à nouveau. –

0

C'est une très bonne idée de mettre des données qui ne sont pas 100% nécessaires pour l'application dans un cache jetable. Pendant les heures de pointe, ils seront jetés, économisant ainsi plus de ressources pour des besoins plus urgents.

En route, en bref.

+0

Je ne voudrais pas appeler des caches de portée de session le chemin à parcourir. – sfussenegger

+0

Peut-être, je me trompe. Esprit à élaborer? –

+0

C'est exact, Vladimir, c'est juste une partie de l'application. L'utilisateur peut rester connecté à l'application, en gardant la session active, mais sans utiliser * cette * partie particulière de l'application. Ainsi, avec de nombreux utilisateurs, nous permettons à GC de nous éviter les problèmes OutOfMemory. En outre, comme je l'ai mentionné précédemment, il existe un autre stockage où la liste actuelle est stockée. Si je reçois null - pas un gros, il suffit de le charger à partir du stockage. – alexeypro

1

Si vous ne le référencez nulle part ailleurs dans le code et que la JVM a exécuté le récupérateur de place, alors peut risquer que la référence ne soit plus dans la session. La chance est cependant petite, moins que lorsqu'on utilise une référence faible, mais quand même, elle est là.

Je ne ferais pas cela dans une application Web. S'il s'agit de données de portée de session pure (par exemple, utilisateur connecté, panier, etc.), placez-le simplement dans la portée de session de la manière normale. Si la session expire ou est invalide, tout ce qui n'est référencé nulle part ailleurs sera récupéré de quelque manière que ce soit. La portée de la session n'est pas destinée à agir comme un cache "logiciel". Ou s'il s'agit réellement de données de portée de requête, placez-les plutôt dans la portée de la demande. Sinon, utilisez un autre type de magasin de données.

+0

Une autre couche de stockage de données est utilisée. Donc, si je reçois une valeur nulle, je la charge simplement depuis le stockage. Mon idée est de le garder "enveloppé" dans SoftReference juste pour permettre au GC de nettoyer les choses si trop d'utilisateurs sont connectés et certains n'utilisent pas cette partie de l'application, mais sont toujours dans la session active. – alexeypro

+0

Jetez un oeil à Ehcache ou Terracotta. – BalusC