Important Notice - Forums is archived
To simplify things and help our users to be more productive, we have archived the current forum and focus our efforts on helping developers on Stack Overflow. You can post new questions on Stack Overflow or join our Discord channel.

Vaadin lets you build secure, UX-first PWAs entirely in Java.
Free ebook & tutorial.
memory leaks (solved)
EDIT: apparently this isn't a threadlocal or Appfoundation issue, it was related to session management, which it would seem it's pretty dangerous if left unchecked
I have a ThreadLocal variable set to the class extending Application (the entry point class), say MyApplication class.
It's initialized and used like this:
@Override
public void transactionEnd(Application application, Object transactionData) {
...
if (application == ReallotoApplication.this) {
ReallotoApplication.currentApplication.set(null);
ReallotoApplication.currentApplication.remove();
}
}
@Override
public void transactionStart(Application application, Object transactionData) {
if (application == ReallotoApplication.this) {
ReallotoApplication.currentApplication.set(this);
}
}
The problem starts when I close the browser windows, which triggers this:
mainWindow.addListener(new Window.CloseListener() {
@Override
public void windowClose(CloseEvent e) {
if (ReallotoApplication.currentApplication.get() == ReallotoApplication.this) {
ReallotoApplication.currentApplication.set(null);
ReallotoApplication.currentApplication.remove();
}
close();
}
});
and this:
@Override
public void close() {
if (ReallotoApplication.currentApplication.get() == this) {
ReallotoApplication.currentApplication.set(null);
ReallotoApplication.currentApplication.remove();
}
super.close();
}
but watching in VisualVM, I see all the ReallotoApplication instances sticking after I closed the browser window (and close() triggered), and even if I call garbage collector from VisualVM a couple of times, they don't go away, which means it's a memory leak. I left for 30 mins, but they were still. I also tested if the session timeout was involved, it seemed not. Experimenting around it seems that only when I close the browser window on the application it remains stuck in memory, if I press exit which goes on to call close() it does not.
How to fix this please? I want the ReallotoApplication instances to go away after close() is triggered, or browser tab/window is closed
I'm using Tomcat 7.0.16.0 and Vaadin 6.7.3
I had this enabled in my application init()
// ((WebApplicationContext) this.getContext()).getHttpSession()
// .setMaxInactiveInterval(86400);
Apparently there isn't any leak if session manages to expire... :grin:
Also, all the code needed to handle browser window/tab close is this (removing the threadlocal instance makes no difference):
// INFO: this closes the application if the user refreshes the page
mainWindow.addListener(new Window.CloseListener() {
@Override
public void windowClose(CloseEvent e) {
close();
// if you don't invalidate, a malicious user can kill your
// server with an out of memory error, because each refresh will
// leave an instance in memory
((WebApplicationContext) ReallotoApplication.this.getContext())
.getHttpSession().invalidate();
}
});
While having some peculiar behaviour:
I open an application instance in Firefox, then,
I open 4 application instances in IE tabs, then
I close the 4 application instances in IE tabs
What happens is only one instance disappears immediately from memory.
If I close the Firefox instance, again, only one instance disappears from memory.
It seems this only closes one instance per browser for some reason, everything else that was opened in that browser, separate windows and tabs remain for a while.
After the session expires the 3 instances remaining disappear too.
Note that in IE8, each tab is really a window instance, and result in an application instance being stuck in memory, though sometimes it still manages to break consistency by displaying another instance (I think), in which case I get an "Communication problem: invalid security key" error
Also note that if you don't register a close listener like the above one, refreshing the page won't cause instances to remain in memory if refreshing in Firefox, but if refreshing in IE8, each refresh creates an instance server side, which will remain until session timeout. In a flood this will result in an out of memory error
How are you creating the 4 different sessions in the 4 different tabs ? Can you print the sessionId (get it from your http request through a listener) on each tab to see which is which ?
By "Note that in IE8, each tab is really a window instance", I meant each tab is an internet explorer instance, or internet explorer window, such as opening a new internet explorer window.
That's why you get different sessions in different tabs.
If you refresh same tab in IE8 or Firefox, regardless, you get a different session ID each refresh.
Try it yourself in IE8, implement
public class ReallotoApplication extends Application implements
ApplicationContext.TransactionListener, [b]HttpServletRequestListener[/b]
then add
@Override
public void onRequestStart(HttpServletRequest request,
HttpServletResponse response) {
[b]System.out.println(request.getSession().getId());[/b]
}
Refreshing:
IE8
0E078B57132CA57B4A647ABFD6D28AB5
8CE7CCD6F0E4A6CA241FA2ECF23E5AA2
8CE7CCD6F0E4A6CA241FA2ECF23E5AA2
8CE7CCD6F0E4A6CA241FA2ECF23E5AA2
C5EFA308F41ABFFDD5CFECB3C3874F0E
C5EFA308F41ABFFDD5CFECB3C3874F0E
C5EFA308F41ABFFDD5CFECB3C3874F0E
46A65BA793E877AAFB824FDEF150FFE2
46A65BA793E877AAFB824FDEF150FFE2
Firefox
7BFD5D579CC1DAB92E96A7899A8BF378
BF0D24444B2C8A2D2AA3BE8A9447A802
BF0D24444B2C8A2D2AA3BE8A9447A802
BF0D24444B2C8A2D2AA3BE8A9447A802
127783654F36E7FE7F4C14905DBD0A1B
127783654F36E7FE7F4C14905DBD0A1B
127783654F36E7FE7F4C14905DBD0A1B
0D0BB8650A9AA9FFA0BB08020A2FD067
0D0BB8650A9AA9FFA0BB08020A2FD067
0D0BB8650A9AA9FFA0BB08020A2FD067
DA5CF7DFC98980CBDBD7AF89CE863FCF
DA5CF7DFC98980CBDBD7AF89CE863FCF
DA5CF7DFC98980CBDBD7AF89CE863FCF
0A765239D9AB6828974605E2CE8BE972
0A765239D9AB6828974605E2CE8BE972
New tabs:
IE8
9D47EB13AE95FA91D162D358CA16B7AA
9D47EB13AE95FA91D162D358CA16B7AA
3EA79F892845A85F7D3E4B21DF891515
3EA79F892845A85F7D3E4B21DF891515
03359286DC47EA3BAC4361525AB9CEAF
03359286DC47EA3BAC4361525AB9CEAF
Firefox
3390B2B3936428F81F7353A34D3494F9
3390B2B3936428F81F7353A34D3494F9
3390B2B3936428F81F7353A34D3494F9
3390B2B3936428F81F7353A34D3494F9
3390B2B3936428F81F7353A34D3494F9
3390B2B3936428F81F7353A34D3494F9