About Sessions, Conversations, and the Garbage Collector 10 Jun 2012
A couple of days ago, I had a discussion with a developer about the notion of web conversation.
More precisely, about its utility. During this discussion, we ran into some basic misconceptions
that, IMHO, no web developer must do. Conversation (or flows) are good features of the recent
frameworks (Spring, JSF) because they allow to save information across several user requests without
putting them into the session. For instance, this can be very useful for wizards. Putting these
information into the session asks for manual maintenance, and in particular for manual collection.
This is usual error prone and should be avoided. The problem being that the user rarely logs out
before closing the browser. Thus, HttpSession.invalidate()
does not get a chance to be called
and the session remains active until the timeout occurs (usually 20 minutes later).
The person I was talking with, though that it is not necessary to care about that. In his view, the garbage collector will take care of this and that it can be forced. We discuss the matter a bit deeper and here are some myths that I think must be rebutted.
First assumption: I can force the garbage collection
This is not true, actually according to the Java documentation:
Calling the gc method suggests that the Java Virtual Machine expend effort toward recycling unused objects in order to make the memory they currently occupy available for quick reuse. When control returns from the method call, the Java Virtual Machine has made a best effort to reclaim space from all discarded objects.
System.gc()
suggests the garbage collection, it does not enforce it. This signals that you
would like the garbage collector to do its job, but there is no guarantee whatsoever. It is only
possible to enforce garbage collection by writing your own garbage collector, but you cannot expect
all garbage collectors of all the possible VM to act similarly. Therefore, relying on this
assumption is not portable.
Second assumption: If I close the browser the session and its objects are collected
Even If it would be possible to enforce the garbage collection, it is of no use as long as there
remains a single reference to the objects to collect. Again, this is absolutely not the case.
Remember that closing the browser does not mean anything to the server. It would, in theory possible
to imagine something with an ajax call that traps the close event of the browser and does a
HttpSession.invalidate()
. This is quite complex to do in a cross-browser manner and gives no
guarantee. Therefore, the data attached to the session will be kept in memory until the session
timeout. This is precisely the beauty of conversation scopes, the developer just tells when the
conversation starts and when it ends. Usually, user do not stop in the middle of a conversation,
they tend to finish it. At least, more often that they click on logout.
Third assumption: Anyway this does not represent a huge amount of memory.
Let us take a simple example: a standard business application that, at some point in the business process, requires a tree for shop selection. This kind of interactions requires several client-server communications and therefore several requests. A temptation would be to put the tree in the session scope. Let us say that 10,000 (logical) users log into the application, for instance from 09:00 am to 09:30 am. If each session requires 100 KB (trees are huge even with lazy loading), we end up with 1G memory(only for the tree). As most of the users do not click on logout, you rely on the timeout to free these objects.
Conclusion
Using request scope of conversation scope over session scope is a good practice as it frees you
from managing the garbage collection. The code is therefore cleaner and more efficient.
This can be done with JSF’s @ConversationScoped
or with Spring Webflow’s Conversation
.