# ZK 6.5.2 and memory leak stopping Tomcat 7.0.32

claudioveryant
9 1

Hi all,

I work with:

• Ritchlet and ZK 6.5.2 with Comet Server Push using zkmax.jar;
• Tomcat 7.0.32;

After runnting the attached program in a browser, I click:

• on Stop button in Tomcat Manager;
• on Find Leaks;

and in message field I found the follow: "The following web applications were stopped (reloaded, undeployed), but their classes from previous runs are still loaded in memory, thus causing a memory leak (use a profiler to confirm): /myapp"

My test program is IsRichletThreadServerPush. The program creates a Thread that creates a windows. After a "for" creates a Textbox and append it to the window, each time calling before "Executions.activate(dsk);" and after "Executions.deactivate(dsk);" Here the source:

import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.Desktop;
import org.zkoss.zk.ui.GenericRichlet;
import org.zkoss.zul.Textbox;
import org.zkoss.zul.Window;

public class IsRichletThreadServerPush extends GenericRichlet {
public void service(Page p) {
final Desktop dsk = Executions.getCurrent().getDesktop();
final Page page = p;
if (dsk.isServerPushEnabled() == false)
dsk.enableServerPush(true);
public void run() {
Window w = null;
int topwin = 30;
for (int i = 0; i < 10; i++) {
try {
Executions.activate(dsk);
} catch (InterruptedException e ) {
}
if (w == null) { // only the first time I create the window
w = new Window("TestServerPush", "overlapped", true);
w.setHeight("600px");
w.setWidth("600px");
w.setStyle("position:absolute;border:solid 1px;");
w.setTop(new Integer(topwin)+"px");
w.setLeft("50px");
w.setPage(page);
topwin += 20;
}
final Textbox tb = new Textbox();
tb.setStyle("position:absolute;");
tb.setLeft(new Integer(topwin + (i * 20)).toString()+"px");
tb.setTop(new Integer(topwin + (i * 30)).toString()+"px");
tb.setText(new Integer(i).toString());
tb.setParent(w);
try {
Executions.deactivate(dsk);
} catch (Exception e ) {
}
}
if (dsk.isServerPushEnabled() == false)
dsk.enableServerPush(false);
}
}.start();
}
}


Claudio

delete retag edit

Sort by » oldest newest most voted

avidD
166 2

Hi Claudio,

      Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors(),
.setNameFormat(this.getClass().getSimpleName() + "-%1\$d")
.build());


This should be done at some "central" place. I use a "Registry" class that is accessible via the application context. All your concurrent tasks must be handed over as "Task" instances to the thread pool which then reuses threads. This is more efficient and safer than creating your own threads.

On shutdown of the application, e.g., in a WebAppCleanupListener, you have to explicitly shut down the thread pool which ends the threads and allows the classes to be GCed.

However, PermGen errors can have many more causes (static variables, ThreadLocals not removed, jdbc drivers, etc.) which will still cause memory leaks.

One more remark, garbage collection in the permanent generation is only enabled if you start tomcat with these flags (if you are running jdk6): -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled

Cheers, David

claudioveryant
9 1

Thanks David, unfortunately, the code of our project must to be compatible to jdk1.4.2 and the java.util.concurrent.Executors are only from jdk1.5.

Anyway I'll try what you told me.

ciao, Claudio

avidD
166 2

Hi Claudio,

sorry for the late response, I used to get notifications from the forums, but apparently something changed.

Yes, maybe this thread thing was a bit too far off-topic. Nevertheless, you really should use the a pool, either provided by the JDK or some utility (maybe something from apache-commons?).

Back to the original problem. I assume the problem is that you never disable serverPush:

if (dsk.isServerPushEnabled() == false) // this is never true in your code
dsk.enableServerPush(false);


Also, you need to enable server push only once (when starting the session) and disable it once (when ending the session). This suggests a SessionListener is a good place to do so.

Cheers, David

claudioveryant
9 1

Thanks David, yes the test is wrong and I will edit and test the change. I am now engaged in the output of a new release but I will soon take up the tests on this topic.

Ciao Claudio