Repository navigation
Webapp classloader leaks problem with RiakNode.Builder or RiakClient [JIRA: CLIENTS-962] #660
Description
Activity
- changed the title
[-]Webapp classloader leaks problem with RiakNode.Builder or RiakClient[/-][+]Webapp classloader leaks problem with RiakNode.Builder or RiakClient [JIRA: CLIENTS-962][/+]on Aug 14, 2016 Hi Cong,
What happens if you run
await()on theFuture<Boolean>thatcluster.shutdown()andclient.shutdown()return?@monday0rsunday Also, do you have a minimum reproducing java project you could share to help speed up bug hunting?
So after running the refresh a few times, I see some extra WebAppClassLoaders sitting on the Heap:
If we dig down and "Merge Shortest Paths to GC Roots", it shows something on the Jetty Scanner TimerThread, but no big red flags.

Do you know if you can reproduce this with a console app, or another webapp container?
@monday0rsunday What version of Java are you running?
@monday0rsunday Aha! I think I found our culprit. It looks like the object that gets stuck in memory is one
io.netty.util.internal.IternalThreadLocalMapobject, which isThreadLocal. It looks like this is a known issue that the Netty team has no control over. I'll see if there's a workaround...@alexmoore I'm not sure about version exactly, but there are two major versions I tested: 7 and 8.
@monday0rsunday One workaround is to add the following to your
contextDestroyed(..)method after you callclient.shutdown.get();:io.netty.util.concurrent.FastThreadLocal.removeAll(); io.netty.util.concurrent.FastThreadLocal.destroy();
This seems to allow the most PermGen/Metaspace space to be GC'd (Java 7 running here):
I'll need to do some more investigation to see if there's any more permanent fixes/workarounds for this Netty ThreadLocal issue, or if there's anything else not getting collected.
@alexmoore Thank you, I'll try it and feed back to you.
@monday0rsunday So looking into it more today, if we:
- Add those two lines to cleanup netty
- Start server
- Take Heap Dump Import trifork's PBC Client, Map/Reduce filter support #1
- Touch the xml file to force a redeploy
- Force GC via VisualVM
- Take Heap Dump add file extension so the README renders nicely on GitHub #2
- Compare the dumps
After the refresh + GC, there are no additional instances of any
io.nettyorcom.basho.riakclasses in dump 2, which means that everything in those two libs are getting GC'd over the refresh.There are some new additional objects in dump 2 that I can't find homes for, but I think they are related to the Jetty reload:
Digging further into the big
java.lang.ref.Finalizerdifference, this seems related to the Jar file reloading, same with thebyte[],String, etc differences. Those objects seem to get GC'd later on after everything is reloaded or finalized.Please try adding those two lines to your web service
contextDestroyed(...)method and let me know if you see any more errant behavior.@alexmoore yes, after adding two lines of code, I haven't seen any leaked WebAppClassLoader. Although there're some other leaked classes, but they won't be more serious than WebAppClassLoader, so the problem can be considered to be solved.





I'm using Riak java client (2.0.4) for our jax-rs services and I've encountered permgen OOM leak when reloading services.
I've created an example, just using this Listener (and uncomment cluster/client code) for any webapps, and seeing permgen space increase when reloading services (at least 2 times).
Thanks,
Cong Nguyen