Скорость Java-приложений растет после добавления выхода журнала - программирование

Скорость Java-приложений растет после добавления выхода журнала

Мы наткнулись на довольно странную проблему ИМО. Наши клиенты жалуются на скорость, с которой наше приложение импортирует и обрабатывает данные из файлов [filesize 1kB cca, время, необходимое для импорта файла в обычных условиях, составляет 4-10 секунд, в зависимости от общей рабочей нагрузки. Да, это много]...

Итак, мы начали изучать его, но произошло что-то совершенно неожиданное: после вставки отладочных журнальных выходов в определенные части кода [не влияя на логику в противном случае] импорт ускорялся довольно много: 300 мс-2200 мс/файл в зависимости от общая рабочая нагрузка.

Используемый язык: Java

JDK 6_34 на моей станции [не знаю, какие версии используют мои коллеги]

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

Насколько эта ситуация знакома кому-либо?

P.S.: Я надеюсь, что этот вопрос действительно принадлежит. Если нет, я искренне извиняюсь.

изменить:

как для ведения журнала, мы используем log4j.

ОС: Windows XP/моя машина. Один коллега имеет то же самое, другой использует Win7/

CPU: E7500 @2,93 ГГц

ОЗУ: 2 ГБ DDR2

Другая машина в основном такая же. Конфигурация третьего неизвестна мне, поскольку она новая, а не моя рабочая станция.

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

Больше всего меня беспокоит то, что мы используем платформу, для которой у нас нет источника, потому что мы хорошо заплатили за лицензию, но не из источникa > . <

4b9b3361

Ответ 1

Добавление ведения журнала добавляет точки синхронизации к вашей логике. Возможно, то, что вы видите, является побочным эффектом (нечетным) этого.

Ответ 2

Моя теория заключается в том, что добавление ведения журнала меняет что-то в шаблонах планирования потоков приложений.

Обычно это не имеет значения. Но если основная проблема в вашем приложении связана с планированием потоков, то неудивительно, что запись в журнал изменяет наблюдаемое поведение.

Я рекомендую вам проверять соответствующие части вашей кодовой базы для поиска вызовов Thread.sleep(...), вызовов Thread.yield(), мест, где выполняется ваш опрос, и т.д. Также подумайте, что это может происходить в стороннем библиотечном коде.

@OldCurmudgeon отвечает на две простые версии того, что вы должны искать. Даже использование sleep(0) является расточительным, хотя оно лучше, чем sleep(N), где N значительно больше нуля.

Ответ 3

Были ли у вас возможность воспроизвести проблему с оригиналом клиента (т.е. могли ли вы извлекать файлы и использовать их на 4-10 секунд, как вы упомянули) на компьютере, который вы используете?

Если нет, то слишком много факторов, чтобы конкретно предоставить log4j кредит. Я с Уилфом на этом. Нет никакого способа, чтобы добавление журналов могло достоверно увеличивать скорость фрагмента кода... по крайней мере, я не могу думать о нем.

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

Ответ 4

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

В прошлом, когда вы наблюдали странное увеличение задержки, это было связано с сетевыми вызовами, такими как DNS-поиск. Когда вы обрабатываете файл, вы получаете доступ к внешнему приложению/сетевому сервису?

Ответ 5

Вы ищете спиновый цикл.

Где-то в вашем коде (или базовой структуре) у вас есть код, который выглядит примерно так:

while (!ready()) {
  // Do next to nothing.
}

или что-то, что сводится к этому.

По сути, цикл вращается так быстро, что ресурс, который он ждет, не получает достаточно времени, чтобы стать доступным. Обычно вы также видите странное использование процессора.

Журналирование облегчает условие, поскольку оно замедляет цикл, тем самым позволяя ресурсу стать готовым.

Вам нужно изменить его на что-то вроде:

while (!ready()) {
  Thread.currentThread().sleep(0);
}

или, в идеале, использовать надлежащий механизм блокировки.