On 04/04/2012 05:40 PM, Charles Duffy wrote:
Howdy --
I'm occasionally getting the following after a BaseX instance has been up and accepting queries for some time:
[XPST0017] Class cannot be initialized: PermGen space.
As I understand it, PermGen space is used during classloading. I'm using a Java extension (packaged in a xar); as BaseX has a fair bit of custom code around classloading, this seems the obvious first place to start looking. That said -- has anyone already seen this?
(By the way -- without looking at the code, I would expect new classloading to only happen if the repo holding this plugin is being uninstalled and reinstalled; is this expectation accurate, or are plugins reloaded within a running instance more frequently?)
Using jmap and jhat, it's clear that we have a classloader leak -- org.basex.util.JarLoader has 13 instances in memory, each of which is referred to by a ModuleLoader instance, two java.lang.Package instances (one of which is referred to by my Java module), and separate copies of my 3rd-party module's classes and all their dependencies; this makes the source of the PermGen outage quite clear.
After a bit of digging, it appears that each query generates a new QueryContext, which generates a new ModuleLoader, which generates a new set of Java modules -- in short, that every Java module is completely loaded anew for every query referencing an XQuery module *in the same package* (not necessarily even using the Java module at all).
Is there design intent for this behavior? From where I currently stand, it seems really quite unfortunate -- not only from the perspective of making it easy to exhaust the limited PermGen space, but also for runtime performance.