views:

181

answers:

5

I'm currently wondering what the actual overhead, in the JVM, is for loading extra classes which are never used.

We have code which iterates all the classes in the class path to find classes which implement a certain interface, we then load them.

This allows custom classes to be simply dropped in a directory and they get loaded and registered.

The side affect is that we hit every class in the class path, causing the classes to load. What would be the affect on the JVMs memory?

Does simply loading classes affect the memory much at all?

+4  A: 

As usual, I would advise measuring this for your particular scenario.

Having said that, I'm not sure I'd advise scanning the whole classpath. If you don't control the classpath (it's your customer's, or similar), potentially they could add anything to it, and your process is going to scan anything they drop into their classpath (possibly unrelated to your app).

I'd suggest that you nominate only certain directories/repositories that classes can be uploaded to, and that way you'll restrict the classpath scanning and reduce the chances of inadvertently picking up stuff you don't intend to.

Brian Agnew
Its probably best to have separate locations for the different type of classes the customers can implement.
Neil Wightman
A: 

Yes, this forces the VM to load the class file and examine it (which can be a performance problem). Moreover, if you're using a Sun VM, then these classes will stay in memory forever. the Sun VM puts classes in the so called "PermGen" space which is never garbage collected unless you specify a special option.

So this is generally a bad idea but there are two simple workarounds:

  1. Check the name of the class (the filename). Repeat the name of the interface in the name, so you can easily notice what you have to load and what not.

  2. Use two directories. One contains normal classes, the other the one all those which you want to always load.

Aaron Digulla
Not true - only the classes loaded by the system class loader can never be unloaded.
Michael Borgwardt
So why did I get lots of OutOfPermGen when developing with Groovy which comes with its own classloader?
Aaron Digulla
+2  A: 

If you use a separate ClassLoader to load those classes and are very careful not to create any references to those classes or instances of them, then when the ClassLoader becomes eligible for garbage collection, so do the classes.

Thus, you could avoid unnecessarily clogging your PermGen space by doing 2 passes with separate ClassLoaders: one to load all the classes and identify those you want to keep, and another to actually use them.

Michael Borgwardt
+1  A: 

Won't using ClassLoaders in this way have unintended side-effects? Like running static initialisers and so on.

You could use the ServiceLoader mechanism, but if that doesn't suit, you can inspect classes without using ClassLoaders - byte manipulation libraries like BCEL and ASM can be used to just inspect classes.

McDowell
Yes, its a pain when it calls the static initialisers. Its caused some deadlocks in the past too :(
Neil Wightman
Yeah, who knows what static initializers are doing in classes you don't control!
John Gardner
A: 

A "far out there" suggestion:

could you do the same thing but without actually using the VM? the class file spec is documented, couldn't you write your own app to just read the class files and figure out if they implement your interface/whatever without actually loading them?

That would get you the ability to scan any directories but without any worry of loading classes or static intializers or anything like that.

John Gardner