Вопрос-ответ

Real differences between "java -server" and "java -client"?

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

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

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


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


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

Переведено автоматически
Ответ 1

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

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


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


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


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


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


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


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


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


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

-client

Выбирает виртуальную машину Java HotSpot Client.

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



2022: Хольгер ссылается в комментариях на обнаружение компьютера JavaSE6 / серверного класса, добавляя:


Только в 32-разрядных системах Windows, -client когда-либо выбирался безоговорочно.
Другие системы проверяли, относится ли машина к “серверному классу", что выполнялось при наличии не менее 2 ядер и не менее 2 ГБ памяти.


Это объясняет, почему уже довольно давно почти все использует -server. Даже самые дешевые компьютеры, которые вы можете найти, являются машинами "серверного класса”. Сборки Sun / Oracle 64 даже не поставлялись с клиентской JVM.


Ответ 2

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

Ответ 3

клиентская и серверная системы - это разные двоичные файлы. По сути, это два разных компилятора (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--) {
}
}
}

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

With -client:
java.exe -путь к классу клиента C:\mywork\classes com.blogspot.sdoulger.Тест цикла
Затраченное время: 766

С -сервером:
java.exe -сервер -путь к классу C:\mywork\classes com.blogspot.sdoulger.Проверка цикла
Затраченное время: 0

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

Ссылка

Ответ 4

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

java jvm