имеет ли смысл флаг java-сервера? - PullRequest
1 голос
/ 22 января 2010

Я думаю, что все знают о параметре JVM командной строки -server. Имеет ли какой-либо смысл при запуске приложения Java в качестве сервера ??

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

boolean flag=true;
while(flag) { 
   if(checkMethod()) {
      flag=false;
   }
} 

[EDIT] этот код будет работать нормально (одинаково) в обоих сценариях 1. без -server и 2. с -server. Обновится еще раз с соответствующим тестируемым кодом.

оно никогда не выйдет из цикла пока ..

Мы только что начали новый проект. Должны ли мы начать использовать -server для тестирования?
Вы используете это?

И мне интересно, действительно ли это имеет смысл и действительно важно, почему в официальных документах / руководствах по серверным продуктам, таким как tomcat / jetty / geronimo и т. Д., Никогда не используется тег / show -server в примерах кода ????

Приветствия

Ответы [ 6 ]

7 голосов
/ 22 января 2010

Это не может быть правдой. Java никогда не выполнит код неправильно, независимо от того, какие переключатели вы добавите. Он может оптимизировать вызов checkMethod, только если будет доказано, что он всегда возвращает одно и то же значение.

Как правило, ключ -server помогает повысить производительность, более агрессивно оптимизируя (предполагается, что подпрограммы будут жить дольше и будут вызываться чаще). Раньше у них были столбцы для Java и Java-сервера в Shootout языка программирования, но, похоже, они убрали прямую «Java», потому что она никогда не опережала Java-сервер.

Кажется, я помню, что -сервер несколько увеличил тесты.

4 голосов
/ 22 января 2010

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

class Runner extends Thread
{
boolean stop = false;
public void run()
{
   while (!stop)
   {
       doSomething();
   }
}
public void exit()
{
    stop = true;
}
}

Вызов метода exit () без оптимизации приведет к тому, что поток выйдет из цикла, когда оптимизация включена, оптимизатор может догадаться, что цикл никогда не закончится, и заменит тест простым переходом, так как останов не является энергозависимым не изменяется внутри цикла.
Такое поведение следует ожидать, так как переменная, к которой обращаются несколько потоков, должна быть объявлена ​​как volatile или доступна только через синхронизированные методы.
только что вспомнил, что в Thread есть метод stop (), заменил его на exit () для ясности.

2 голосов
/ 22 января 2010

Ваш список кода опасен, потому что он не потокобезопасен, а не из-за используемой виртуальной машины. Это опасно на всех виртуальных машинах. Но на ваш вопрос: виртуальная машина сервера более агрессивна в JIT-кодировании вашего кода, поэтому она имеет тенденцию работать быстрее за счет более медленного запуска приложения. Обратите внимание, что виртуальная машина сервера используется по умолчанию в некоторых аппаратных конфигурациях для некоторых версий Java (например, для Java 5, флаг -server подразумевается, если на хосте 2 или более ГБ памяти и 2 или более ядер).

1 голос
/ 22 января 2010

Возможно, некорректный код (не ориентированный на многопотоковое исполнение) может работать правильно без -server, но с ним не получится.

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

1 голос
/ 22 января 2010

Опция -server просто настраивает компилятор точно в срок, чтобы сделать различные компромиссы. Сервер JIT будет выполнять более тяжелые оптимизации кода раньше, что замедляет запуск, но хорошо подходит для долгоживущих процессов. Клиентский JIT пытается сократить время запуска и со временем оптимизирует его. См. Java HotSpot документацию для получения дополнительной информации

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

Оптимизация никогда не должна изменять поведение вашей программы, как в вашем примере.

0 голосов
/ 22 января 2010

Флаг -server не меняет семантику выполнения. В вашем примере JVM, которая препятствовала бы выходу из цикла, была бы просто неправильной, как в «не соответствует спецификации Java», а также как и «просто неправильно».

Что может сделать оптимизация в целом и '-server' в частности, это изменить правила для неопределенного. Java довольно жестко определен, но у него есть несколько нечетких мест, в частности в отношении с плавающей запятой и несинхронизированного одновременного доступа к памяти.

Например, с таким кодом:

int x = 0, y = 0;
void set(int x, int y)
{
    this.x = x;
    this.y = y;
}
int getX()
{
    return x;
}
int getY()
{
    return y;
}

и предполагая, что некоторый код в потоке вызывает set (1, 1), а другой вызывает getY (), затем getX (), тогда без синхронизации getY () может вернуть 1 (новое значение) и getX () может вернуть 0 (старое значение): первый поток устанавливает x, затем y на уровне источника, но с точки зрения другого потока запись в y может произойти до записи в x.

Код, основанный на порядке обновления из другого потока без явной синхронизации (с «синхронизированным» или «изменчивым»), является ошибочным, но может избежать обнаружения с помощью тестов. Флаг -server делает JVM более удовлетворяющим триггеру при таком переупорядочении и, таким образом, может показывать ошибку. Но флаг -server здесь не ошибочен: код:

Это означает, что использование -server для тестирования на самом деле хорошая идея: это может помочь выявить некоторые ошибки. Для кода без ошибок флаг -server является безопасным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...