Реальные различия между “java-сервером” и “java -клиентом”?

StackOverflow https://stackoverflow.com/questions/198577

  •  10-07-2019
  •  | 
  •  

Вопрос

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

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

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

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

Это было полезно?

Решение

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

Из главы 2 документа ( Архитектура движка производительности Java HotSpot ):

  

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

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

     

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

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

  

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

     

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

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

<Ч>

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

-client
  

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

Другие советы

Наиболее заметным непосредственным отличием в старых версиях 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 вместе со множеством других статистических данных.

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

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

 введите описание изображения здесь

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

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--) {
        }
    }
}

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

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

С -server:
 java.exe -server -classpath C: \ mywork \ classes com.blogspot.sdoulger.LoopTest
 Время проведено: 0

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

Ссылка

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

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

  

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

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

  

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

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

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

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

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

Из Goetz - Java-параллелизм на практике:

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

    Листинг 3.4. Считать овец.

         

    <код>   летучий логический спящий;   ...   пока (! спит)      countSomeSheep ();

Мой акцент. YMMV

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

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

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

В «No Fluff Just Stuff» и Кен Сипе, и Гленн Ванденбург ведут отличные разговоры о подобных вещах.

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

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

IIRC:

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

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

У меня была пара скриншотов, которые действительно хорошо показывали разницу, но я не могу воспроизвести, так как у меня 64-разрядная JVM, которая реализует только виртуальную машину сервера.(И я не могу побеспокоиться о том, чтобы загрузить и переработать 32-разрядную версию в своей системе.)

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

При выполнении перехода с версии 1.4 на 1.7 (< 1.7.0_55 "). Мы заметили, что нет таких различий в значениях по умолчанию, назначенных параметрам heapsize | permsize | ThreadStackSize в клиенте & amp; режим сервера.

Кстати, ( 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. Считается, что реальную разницу можно было бы измерить во время выполнения в зависимости от вашего поведения приложения

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top