15

我正在尝试为旧框架实施一些单元测试。我正在尝试模拟数据库层。不幸的是,我们的框架有点旧,并且没有完全使用最佳实践,因此没有明确的关注点分离。我有点担心尝试模拟数据库层可能会使 JVM 加载大量甚至不会使用的类。

我不太了解类加载器,所以这可能不是问题。有没有办法在特定 ClassLoader 加载的所有类中达到峰值,以证明引擎盖下发生了什么?

4

4 回答 4

45

您可以创建自己的 Classloader 并在单元测试期间使用它来加载。让您自己的自定义类加载器打印出它在做什么。

或者,如果您只想知道加载了哪些类,请执行以下操作:

java -verbose:class
于 2009-11-10T02:02:12.587 回答
18

请注意,使用

java -verbose

会产生巨大的产出。将输出记录到文件中,然后使用 grep。如果你有“三通”过滤器,你可以试试这个:

java -verbose | tee classloader.log
grep class classloader.log
于 2009-11-10T02:16:25.727 回答
3

我不确定。但我认为有一种方法可以做到。不过,这可能过于荒谬。您可以尝试方面并为 loadclass 放置一个切入点。也可能 jvm 参数-verbose可能会有所帮助。

于 2009-09-22T15:41:44.753 回答
1

作为一种替代方法,对于您提到的特定类加载器,您可以使用此代码片段。如果需要,只需更改 obj 变量的值。

Object obj = this;
ClassLoader classLoader = obj.getClass().getClassLoader();
File file = new File("classloderClasses.txt");
if (file.exists()) {
    file.delete();
}
if (classLoader != null) {
    try {
        Class clClass = classLoader.getClass();
        while (clClass != ClassLoader.class) {
            clClass = clClass.getSuperclass();
        }
        java.lang.reflect.Field classesField = clClass.getDeclaredField("classes");
        classesField.setAccessible(true);
        Vector classes = (Vector) classesField.get(classLoader);
        FileOutputStream fos = new FileOutputStream("classloderClasses.txt", true);
        fos.write(("******************** " + classLoader.toString() + " ******************** " + "\n").getBytes());
        fos.write(Arrays.toString(classes.toArray()).getBytes());
        fos.close();
    } catch (Exception exception) {
        exception.printStackTrace();
        // TODO
    }
}
于 2017-09-05T13:18:01.007 回答