简体   繁体   English

我该如何对GC进行单元测试?

[英]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. 对于项目,我们需要一种方法来运行用户脚本,这些脚本可以带有附加类的附加JAR文件。

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"? 我特别需要知道:附加的JAR中的所有类都是“卸载的”吗?

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". 注意:我不是在寻找适用于所有Java版本的100%超级防水解决方案,从1.0到7.现在,我只需要比“我不知道”更好。

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. 相反,我将使用-XX:-TraceClassUnloading运行JVM,并查看有问题的类是否显示在跟踪输出中。

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). 可能的最佳选择是确保加载的jar由特定的类加载器加载,然后丢弃该类加载器(在丢弃所有对象之后)。

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. 如果您使用的不仅仅是纯Java工具,那么可能需要考虑OSGi容器。 Most of the established OSGi container implementations explicitly test class unloading. 大多数已建立的OSGi容器实现都明确地测试了类卸载。

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()) 为此,我将创建一个用于加载该JAR的ClassLoaderWeakReference ,然后运行该脚本,然后调用System.gc() ,然后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. 在Java中泄漏内存的典型方法是使用静态引用。 A static reference is only static within the ClassLoader of the class that contains it. 静态引用仅在包含它的类的ClassLoader中是静态的。 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. 因此,如果您使用ClassLoader加载您的用户脚本,您自己管理(并且您应该这样做),那么只要您的类加载器本身,引用(静态或非静态)就可以用于GC。

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. 所以你必须非常小心你公开的API。 Another way is if they would make a static reference to their class in a class from another ClassLoader. 另一种方法是,如果他们在另一个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. 但是我想你可以用任何像样的分析器跟踪课程卸载。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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