A 12-year-old bug in JDK, still out there leaking memory
plumbr.eu
plumbr.eu
java.net.HttpURLConnection and java.net.HttpURLConnection will attempt to use Keep-Alive and keep connections open for you (which should be a great performance boost if you are making many connections to the same hosts over and over again), but they do so silently and without any obvious documentation on how you can control that behavior in your own code. This leads to lots of headaches if you as a developer actually want to be able to control the connection behavior - for instance, there are quiet and undocumented bugs with HttpsURLConnection not being able to reuse the connection unless you consume all of the response stream (even if you call connection.close() and stream.close() explicitly).
There is also no obvious way to monitor the sun.* code that does the actual keep-alive work to see how many connections are open, to verify if it is able to use keep-alive or if it has to keep opening new connections, etc (without resorting to tcpdump).
The classloader leak is the root problem but the trigger in this case is the fact that the framework code is trying to a whole lot of extra, undocumented, silent work for you. The ability to disable keep-alives in the code that caused the initial report could have been a viable workaround.
From the bug report: Submit Date: 2010-12-22 Resolved Date: 2011-03-10 That's less than 3 months.
It's a tad misleading, but it's "still out there waiting to bite you" because of Java 6 still being widely used.
It's also pretty rare for folks to use that http client. It's normally the case that an apache commons or netty http client is used.
Over the years I've found that while the Hotspot team seemed pretty sharp, the monkeys writing the library code were incompetent in implementation and negligent in repair even for core stuff. I eventually gave up submitting error reports. Don't even get me started on java.util.Random. :-(
In the ArrayList case, IIRC (it was years ago) the issue was the now-notorious RangeCheck function. For example, get(index) does this:
RangeCheck(index);
return elementData[index];
get() could be inlined, but because RangeCheck threw an exception if the index was >= size, RangeCheck was not inlined. But if you did this: if (index >= size)
RangeCheck(index);
return elementData[index];
... you could bypass it and calls to get() would involve inlined code unless the exception was triggered. Same went for set and add. Recent versions of HotSpot have mooted this now.Back in the days (circa 2006 or so) when similar issues were very common but the knowledge wasn't that much out, we'd fix the issue by changing one of the "Sun JVM / Tomcat / I-don't -remember-which" component. For example switching to a non-Sun JVM or switching form Tomcat to Caucho/Resin etc.
Or simply just starting the SUN JVM with a bigger PermGen.
It's kinda sad to see how many PermGen issues there has been throughout the years.