Жадная загрузка класса Java

Я пытаюсь провести сравнительный анализ JVM, работающих на различном оборудовании и платформах ОС. Я создал алгоритм для проверки частей JVM, которые мне интересны, и намереваюсь запускать этот алгоритм много раз, чтобы найти приличное среднее значение.

Когда я запускаю тест, я обнаруживаю, что первый запуск значительно дольше, чем последующие:

132ms
86ms
77ms
89ms
72ms

Я подозреваю, что классы загружаются лениво, что создает большие накладные расходы при первом запуске. Хотя это действительно функция, которая, как я полагаю, уникальна для каждой JVM, на данный момент она меня не интересует.

Есть ли стандартный параметр или свойство командной строки для быстрой загрузки классов? или у кого-нибудь есть другие теории?

Ответов (6)

Решение

Самый простой способ - игнорировать первый запуск. (Если это действительно так). Примечание: если вы запустите один и тот же код 10 000 раз, он будет компилировать код дальше, и вы получите лучшие результаты, поэтому вы можете проигнорировать первые 10 000 результатов для некоторых микротестов.

Некоторые JVM поддерживают активную загрузку, но я не думаю, что JVM Sun поддерживает.

JWrapper поддерживает AOT https://www.jwrapper.com/features

Правило №1 для тестирования Java: первые 15000 запусков метода (или около того) не представляют интереса.

Эта ветка содержит несколько хороших советов: как мне написать правильный микротест на Java?

Используйте java -XX:+TraceClassLoading для отслеживания загрузки классов.

Используется java -XX:+PrintCompilation для отслеживания, когда методы JIT связаны.

Стандартного параметра командной строки не существует, поскольку он не является частью спецификации JVM. Ленивая загрузка классов является (явно разрешенной как) частью спецификации JVM. Можно было бы использовать Class.forName() перед запуском для загрузки классов, о которых вы знаете, но это не автоматически транзитивно.

Компиляция HotSpot также повлияет на первые несколько запусков - метод интерпретируется несколько раз перед компиляцией, и процесс компиляции занимает некоторое время.

Если вы хотите принудительно загрузить классы, сделайте что-то вроде этого:

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();
            }
        }
    }
}

После загрузки классов во избежание запуска интерпретатора -Xcomp (в реализациях Sun) используйте только скомпилированный код. Таким образом, нормальные приложения могут работать очень медленно, поскольку приходится компилировать весь код, а не только несколько его частей.