渴望java类加载

时间:2009-03-01 10:19:32

标签: java

我正在尝试对在各种硬件和操作系统平台上运行的JVM进行一些基准测试。我已经创建了一个算法来运用我感兴趣的JVM的各个部分,并打算多次运行这个算法来找到一个不错的平均值。

当我运行基准测试时,我发现第一次运行的时间明显长于后续运行:

132ms
86ms
77ms
89ms
72ms

我怀疑这些类是懒得加载的,在第一次运行时会产生很大的开销。虽然这确实是我认为每个JVM都是独一无二的功能,但此时我并不感兴趣。

是否有标准的命令行选项或属性来急切加载类?还是有人有其他理论吗?

6 个答案:

答案 0 :(得分:5)

最简单的方法是忽略第一次运行。 (如果这是有效的事情) 注意:如果您运行相同的代码10,000次,它将进一步编译代码并获得更好的结果,因此您可能希望忽略某些微基准测试的前10K结果。

有些JVM支持急切加载,但我不认为Sun的JVM会这样做。

答案 1 :(得分:5)

如果要强制加载类,请执行以下操作:

public class Main
{
    static
    {
        loadClasses();
    }

    public static void main(final String[] argv)
    {
        // whatever
    }

    private static void loadClasses()
    {
        final String[] classesToLoad;

        // even better, read them from a file and pass the filename to this method
        classesToLoad = new String[]
        {
            "foo.bar.X",
            "foo.bar.Y",
        }

        for(final String className : classesToLoad)
        {
            try
            {
                // load the class
                Class.forName(className);
            }
            catch(final ClassNotFoundException ex)
            {
                // do something that makes sense here
                ex.printStackTrace();
            }
        }
    }
}

答案 2 :(得分:4)

Java基准测试的规则#1:方法运行的前15000次(左右)并不感兴趣。

此主题包含一些可靠的建议:How do I write a correct micro-benchmark in Java?

答案 3 :(得分:2)

使用java -XX:+TraceClassLoading跟踪类的加载。

使用java -XX:+PrintCompilation跟踪方法何时被JIT。

答案 4 :(得分:1)

一旦加载了类,为避免运行解释器,请使用-Xcomp(在Sun实现上)仅运行已编译的代码。以这种方式运行普通应用程序可能会非常慢,因为所有代码都必须编译而不仅仅是几件。

答案 5 :(得分:0)

没有标准的命令行选项,因为它不是JVM规范的一部分。延迟类加载是(明确允许的)JVM规范的一部分。在运行之前可以使用Class.forName()加载您知道的类,但它不会自动传递。

HotSpot编译也会影响前几次运行 - 在编译之前,方法会被解释几次,编译过程需要一些时间。