Реальные различия между "java -server" и "java -client"? - PullRequest
372 голосов
/ 13 октября 2008

Есть ли реальная практическая разница между "java -server" и "java -client"?

Все, что я могу найти на сайте Sun, расплывчато

"- сервер запускается медленнее, но должен работать быстрее".

Каковы реальные различия? (В настоящее время используется JDK 1.6.0_07.)

Ответы [ 11 ]

347 голосов
/ 13 октября 2008

Это действительно связано с HotSpot и значениями параметров по умолчанию ( Параметры Java HotSpot VM ), которые различаются в зависимости от конфигурации клиента и сервера.

С Глава 2 документа ( Архитектура Java HotSpot Performance Engine ):

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

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

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

Так что реальная разница также на уровне компилятора:

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

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

Примечание. В выпуске jdk6 update 10 (см. Update Примечания к выпуску: изменения в 1.6.0_10 ) предпринята попытка улучшить время запуска, но по другой причине, нежели параметры точки доступа. по-разному упакован с гораздо меньшим ядром.


G. Демеки указывает в комментариях , что в 64-битных версиях JDK опция -client игнорируется в течение многих лет.
См. Windows java Команда :

-client

Выбор виртуальной машины клиента Java HotSpot.
64-разрядный JDK с поддержкой в ​​настоящее время игнорирует эту опцию и вместо этого использует виртуальную машину Java Hotspot Server .

87 голосов
/ 17 августа 2012

Наиболее заметным непосредственным отличием в старых версиях Java будет выделение памяти для -client, а не для -server приложения. Например, в моей системе Linux я получаю:

$ java -XX:+PrintFlagsFinal -version 2>&1 | grep -i -E 'heapsize|permsize|version'
uintx AdaptivePermSizeWeight               = 20               {product}
uintx ErgoHeapSizeLimit                    = 0                {product}
uintx InitialHeapSize                     := 66328448         {product}
uintx LargePageHeapSizeThreshold           = 134217728        {product}
uintx MaxHeapSize                         := 1063256064       {product}
uintx MaxPermSize                          = 67108864         {pd product}
uintx PermSize                             = 16777216         {pd product}
java version "1.6.0_24"

по умолчанию -server, но с параметром -client я получаю:

$ java -client -XX:+PrintFlagsFinal -version 2>&1 | grep -i -E 'heapsize|permsize|version'
uintx AdaptivePermSizeWeight               = 20               {product}
uintx ErgoHeapSizeLimit                    = 0                {product}
uintx InitialHeapSize                     := 16777216         {product}
uintx LargePageHeapSizeThreshold           = 134217728        {product}
uintx MaxHeapSize                         := 268435456        {product}
uintx MaxPermSize                          = 67108864         {pd product}
uintx PermSize                             = 12582912         {pd product}
java version "1.6.0_24"

, поэтому при -server большинство пределов памяти и начальные выделения намного выше для этой java версии.

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

Помните также, что вы можете увидеть все детали бега jvm, используя jvisualvm. Это полезно, если у вас есть пользователи, которые или модули, которые задают JAVA_OPTS, или используют сценарии, которые изменяют параметры командной строки. Это также позволит вам в реальном времени отслеживать использование пространства heap и permgen вместе со множеством других характеристик.

32 голосов
/ 23 сентября 2010

Единственное отличие, которое я только что заметил, заключается в том, что в режиме «клиент» JVM, по-видимому, возвращает операционной системе некоторую неиспользованную память, тогда как в режиме «сервер», когда JVM захватывает память, он выигрывает верни это. Вот как это выглядит в Solaris с Java6 в любом случае (используя prstat -Z, чтобы увидеть объем памяти, выделенный для процесса).

28 голосов
/ 07 августа 2015

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

enter image description here

Мы запускаем следующий код с обоими переключателями:

package com.blogspot.sdoulger;

public class LoopTest {
    public LoopTest() {
        super();
    }

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        spendTime();
        long end = System.currentTimeMillis();
        System.out.println("Time spent: "+ (end-start));

        LoopTest loopTest = new LoopTest();
    }

    private static void spendTime() {
        for (int i =500000000;i>0;i--) {
        }
    }
}

Примечание: Код скомпилирован только один раз! Классы одинаковы в обоих заездах!

С -клиент:
java.exe -client -classpath C: \ mywork \ classes com.blogspot.sdoulger.LoopTest
Затраченное время: 766

С -сервером:
java.exe -сервер -classpath C: \ mywork \ classes com.blogspot.sdoulger.LoopTest
Затраченное время: 0

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

Ссылка

21 голосов
/ 18 марта 2013

Онлайн-документация Oracle содержит некоторую информацию для Java SE 7.

На java - странице запуска приложений Java для Windows опция -client игнорируется в 64-битном JDK:

Выберите клиентскую виртуальную машину Java HotSpot. В настоящее время 64-разрядный jdk игнорирует эту опцию и вместо этого использует виртуальную машину Java HotSpot Server.

Однако (чтобы сделать вещи интереснее), под -server говорится:

Выберите виртуальную машину Java HotSpot Server. На 64-битном jdk поддерживается только виртуальная машина Java HotSpot Server, поэтому опция -server неявна. Это может быть изменено в будущем выпуске.

Страница Обнаружение компьютеров *1020* серверного класса содержит информацию о том, какая виртуальная машина выбрана ОС и архитектурой.

Я не знаю, насколько это относится к JDK 6.

15 голосов
/ 13 октября 2008

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

Отредактируйте, чтобы добавить: Вот некоторая информация от Sun, она не очень конкретна, но даст вам некоторые идеи.

14 голосов
/ 10 марта 2016

От Гетца - Java-параллелизм на практике:

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

Листинг 3.4. Подсчет овец.

volatile boolean asleep; ... while (!asleep) countSomeSheep();

Мой акцент. YMMV

5 голосов
/ 13 октября 2008

IIRC, он включает в себя стратегии сбора мусора. Теория заключается в том, что клиент и сервер будут различаться с точки зрения недолговечных объектов, что важно для современных алгоритмов GC.

Вот ссылка в режиме сервера. Увы, они не упоминают режим клиента.

Вот очень полная ссылка на GC в целом; это более базовая статья . Не уверен, является ли этот адрес -server vs -client, но это релевантный материал.

В фильме «Без всякого пуха» и Кен Сипе, и Гленн Ванденбург великие разговоры о подобных вещах.

3 голосов
/ 13 октября 2008

Я не заметил никакой разницы во времени запуска между двумя, но достиг минимального улучшения производительности приложения с помощью "-server" (сервер Solaris, каждый из которых использует SunRays для запуска приложения). Это было под 1,5.

1 голос
/ 22 марта 2015

При выполнении перехода с версии 1.4 на 1.7 («1.7.0_55»). Здесь мы наблюдаем то, что нет таких различий в значениях по умолчанию, назначенных параметрам heapsize | permsize | ThreadStackSize в режиме клиента и сервера.

Кстати, (http://www.oracle.com/technetwork/java/ergo5-140223.html). Это фрагмент взятой из ссылки выше.

initial heap size of 1/64 of physical memory up to 1Gbyte
maximum heap size of ¼ of physical memory up to 1Gbyte

ThreadStackSize выше в 1.7, во время прохождения форума Open JDK, есть дискуссии, в которых утверждается, что размер фрейма несколько выше в версии 1.7. Считается, что реальную разницу можно измерить во время выполнения в зависимости от вашего поведения приложения

...