简体   繁体   中英

How can I unit test GC?

For a project, we need a way to run user scripts that can come with attached JAR files with additional classes.

What are my options when I want to write a couple of tests to make sure normal script don't leave anything dangling behind?

I specifically need to know: Are all classes from the attached JARs "unloaded"?

Note: I'm not looking for the 100% super-watertight solution that works across all versions of Java from 1.0 to 7. Right now, I just need to be better than "I have no idea".

I wouldn't try to unit test this. Instead, I'd run the JVM with -XX:-TraceClassUnloading and look to see if the classes in question show up in the trace output.

The likely best option is to ensure your loaded jars are loaded by a specific class loader, and then to discard that class loader (after discarding all the objects).

As far as unit testing the unloading, if you go with this option, you need to extend your testing framework and customized class loaders to have a "create class loader on demand" flag. Then you load the class once with the flag on, discard the class loader, and attempt to load the class again with the flag off. If the class is truly not reachable, the second attempt should throw a class not found exception. You then wrap your unit tests to pass if they fall into the exception, and fail if they succeed in hitting the line after the second load attempt.

If you are disposed to use more than pure-Java tools, an OSGi container might be a consideration. Most of the established OSGi container implementations explicitly test class unloading.

It looks like what you want to test is that hose scripts don't have a classloader leak .

To do that, I'd create a WeakReference to the ClassLoader used to load that JAR, then run the script, then call System.gc() and afterwards assertNull(reference.get())

This depends entirely on the way you allow the scripts to run. Do they have access to the classes of the rest of the application?

The typical way to leak memory in Java is to have a static reference. A static reference is only static within the ClassLoader of the class that contains it. So, if you load your user scripts using a ClassLoader you manage yourself (and you should do this anyway), then the references (static or not) inside will be eligable for GC as soon as your classloader itself it.

The only way they could work around this, is to add a reference to one of their objects into one of yours. So you have to be very careful with the API you expose. Another way is if they would make a static reference to their class in a class from another ClassLoader.

I don't see a way to fully automate testing for this. But I suppose you could trace the class unloading with any decent profiler.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM