Почему первый вызов java.io.File.createTempFile (String, String, File) в Citrix занимает 5 секунд?

Во время отладки медленного запуска приложения Eclipse RCP на сервере Citrix я обнаружил, что java.io.createTempFile (String, String, File) занимает 5 секунд. Это происходит только при первом запуске и только для определенных учетных записей пользователей. В частности, я обращаю внимание на анонимные учетные записи пользователей Citrix. Я не пробовал многие другие типы учетных записей, но такое поведение не проявляется с учетной записью администратора.

Кроме того, не имеет значения, есть ли у пользователя доступ для записи в данный каталог или нет. Если у пользователя нет доступа, вызов будет завершен через 5 секунд. Если у них есть доступ, вызов займет 5 секунд.

Это на сервере Windows 2003. Я пробовал Sun 1.6.0_16 и 1.6.0_19 JRE и видел такое же поведение.

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

Платформа Eclipse использует File.createTempFile () для тестирования различных каталогов, чтобы увидеть, доступны ли они для записи во время инициализации, и эта проблема добавляет 5 секунд ко времени запуска нашего приложения.

Я полагаю, что кто-то сталкивался с этим раньше и может иметь какое-то понимание. Вот пример кода, который я выполнил, чтобы убедиться, что время действительно отнимает этот вызов. Я также попробовал это со вторым вызовом createTempFile и заметил, что последующие вызовы возвращаются почти мгновенно.

public static void main(final String[] args) throws IOException {
        final File directory = new File(args[0]);
        final long startTime = System.currentTimeMillis();
        File file = null;
        try {
            file = File.createTempFile("prefix", "suffix", directory);
            System.out.println(file.getAbsolutePath());
        } finally {
            System.out.println(System.currentTimeMillis() - startTime);
            if (file != null) {
                file.delete();
            }
        }
    }

Пример вывода этой программы следующий:

C:\>java.exe -jar filetest.jar C:/Temp
C:\Temp\prefix8098550723198856667suffix
5093

person Ben Roling    schedule 09.04.2010    source источник
comment
Также отмечу, что 5 секунд - это стабильно. Я могу запускать это снова и снова, и это всегда займет от 5000 до 5300 миллисекунд. Я предполагаю, что 5 секунд должны быть таймаутом, происходящим на каком-то уровне. Кроме того, это происходит не только на одном сервере. Первоначально поведение было замечено на одном сервере, но я настроил другой сервер и увидел то же самое.   -  person Ben Roling    schedule 09.04.2010
comment
Как указано в комментарии к одному из ответов ниже, я заметил, что это время фактически тратится на первый вызов SecureRandom.nextLong (). Кроме того, я обнаружил, что такое поведение возникает только тогда, когда с пользователем связана группа «Гость». Я могу выполнить этот тест с пользователем и запустить его менее чем за 100 мс, а затем повторно выполнить тот же тест с той же учетной записью, просто добавив этого пользователя в группу «Гости» (без удаления каких-либо ассоциаций других групп у пользователя, который был в предыдущий прогон).   -  person Ben Roling    schedule 20.04.2010


Ответы (3)


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

person Tom Hawtin - tackline    schedule 09.04.2010
comment
Я тестировал безопасную случайную генерацию отдельно, и это не проблема. Я запустил это в отладчике и посмотрел на реализацию createTempFile, заметил безопасную генерацию случайных чисел и подозревал это сам, но исключил это после тестирования этой части специально с помощью тестовой программы. Спасибо за предложение. Сомневаюсь, что в этой системе будет много временных файлов. Я не уверен, что квалифицируется как временный файл, который будет учитываться в отношении того, о чем вы говорите, но каталог c: / temp, в котором я провел свой конкретный тест выше, содержит только 165 файлов. - person Ben Roling; 09.04.2010
comment
Хорошо, я ошибся, когда сказал, что это не безопасная случайная генерация. После небольшой дополнительной отладки я понял, что моего первоначального теста безопасной случайной части этого было недостаточно. Я только протестировал конструкцию new SecureRandom (). Когда я протестировал первый вызов nextLong () в SecureRandom, я увидел, что это был источник 5-секундной задержки. - person Ben Roling; 20.04.2010
comment
Подобная проблема и решение обсуждаются здесь - stackoverflow.com/questions/38942514/ - person apangin; 11.02.2017

Похоже, что медлительность связана с заполнением SecureRandom и только тогда, когда пользователь является членом группы «Гости».

Инициализация начального числа SecureRandom использует Windows Crypto API, который не работает, когда пользователь является гостем, как описано здесь [1]. Установив системное свойство «java.security.debug» равным «all», я могу увидеть следующее, когда программа запущена как гость:

ProviderConfig: Loaded provider SUN version 1.6
provider: Failed to use operating system seed generator: java.io.IOException: Required native CryptoAPI features not available on this machine
provider: Using default threaded seed generator

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

ProviderConfig: Loaded provider SUN version 1.6
provider: Using operating system seed generator

Похоже, генератор потокового начального числа по умолчанию работает довольно медленно. Вот [2] очень старая ошибка, сообщенная Sun об этом.

[1] http://www.derkeiler.com/Newsgroups/microsoft.public.platformsdk.security/2003-12/0349.html.

[2] http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4210047

person Ben Roling    schedule 21.04.2010

Я не эксперт по Citrix, но я знаю кое-кого, кто им является, и кто догадывается:

Учетные записи могут быть настроены таким образом, чтобы чтение / запись приложения перенаправлялись на нелокальные ресурсы. Задержка, которую вы испытываете, может быть связана с инициализацией или производительностью этого разрешения.

Другая возможность заключается в том, что может действовать изоляция приложения, что означает, что чтение / запись файлов происходит в виртуализированных версиях ресурсов.

person Noel Ang    schedule 09.04.2010
comment
Спасибо за эти предложения, но ресурсы являются локальными, и тот факт, что пользователь-администратор может писать в одно и то же место без этой задержки, предполагает, что это не может быть проблемой в любом случае. - person Ben Roling; 10.04.2010