I think the real point is the lifespan of your data .
Think about these two features of HttpSession:
- When in a cluster, the container is responsible for HttpSession replication . This is good (you do not need to manage this yourself), but can be dangerous in terms of performance if it leads to too much sharing ... If your application is not grouped, forget about it.
- HttpSession lifespan can be several minutes or several hours, that is, while the user continues to work. This is ideal for information that has such a lifespan (connection information, preferences, authorization ...). But this is not suitable for data that is useful from one screen to another, let him call it temporary + data.
If you have problems with clustering, the database will take care of that. But be careful, then you cannot cache anything in memory.
Storing in the database has an even longer life (constant between the session and even between reboots!), So the problem will be even worthwhile (except that you are trading the memory problem for a performance problem).
I think this is the wrong approach for data whose lifetime is not expected to be permanent ...
Transient Data
If the data is useful for only one request, then it is usually stored in HttpRequest, excellent.
But if it is used for several requests (interactions within one screen or in a screen sequence, for example, an assistant ..), HttpRequest is too short to store it, but HttpSession is too long. Data must be cleaned regularly.
And many memory problems in HttpSession are associated with such data that is temporary, but have not been cleared (forgotten at all or not cleared by exception or when the user does not respect the regular flow: Back hits, use the previous bookmark, click on another menu or whatever something else).
Library caching has the correct lifetime
To avoid this cleaning effort altogether (and avoid the risks of OutOfMemory when things go wrong), you can store information in a data structure that has the right lifetime. Since the container does not provide this (it is still associated with the application), you need to implement it yourself using the cache library (for example, those mentioned, we use EhCache).
The idea is that you have technical code (not related to one function page, but implemented globally, for example with ServletFilter ...), which ensures that cleaning is always performed after the objects are no longer needed.
You can create this cache using one (or several, as needed) of the following policies to clear the cache. Each policy is associated with functional life expectancy:
- for data related to only one screen (but several requests: screen reload, Ajax requests ...), the cache can store data for only one screen at a time (for each session), call it "currentScreenCache", This ensures that, if the user switches to another screen (even in an uncontrollable way), the new screen will override the "currentScreenCache" information, and the previous information may be garbage collected.
Implementation idea: each request should have its own screen, and the technical code responsible for clearing the cache detects when the current HttpSession identifier does not match the current identifier in the cache. Then it clears or flushes this item in the cache.
- for data used only in a series of connected screens (let's call it a functional module), the same applies to the module level.
Implementation: the same as before, each request should contain a module identifier ...
- for data that is expensive to recompile, the cache library can be configured to store the latest X-calculated ones (the previous ones are considered less likely in the near future). In typical use, the same requests are requested regularly, so you have a lot of cache accesses. With heavy use, the X limit is reached and the memory does not swell, preventing OutOfMemory errors (due to recalculation the next time).
Implementation: file cache libraries support this limiting factor and a few more ...
for data that is valid for only a few minutes, you can cache the cache library to drop it after this delay ...
... much more, see the caching library configuration for other ideas.
Note. Each cache can be a system-wide or user-specific, HttpSession identifier, company identifier, or other functional value ...