[java] “java -server”와 “java -client”의 실제 차이점은 무엇입니까?

“java -server”와 “java -client”사이에 실질적인 차이가 있습니까?

Sun 사이트에서 찾을 수있는 것은 모호합니다

“-서버가 느리게 시작되지만 더 빨리 실행되어야합니다.”

실제 차이점은 무엇입니까? (현재 JDK 1.6.0_07 사용)



답변

이것은 실제로 HotSpot 및 클라이언트와 서버 구성간에 다른 기본 옵션 값 ( Java HotSpot VM 옵션 )에 연결됩니다.

에서 제 2 장 백서 (의 자바 핫스팟 성능 엔진 아키텍처 ) :

JDK에는 클라이언트 측 오퍼링과 서버 애플리케이션에 맞게 조정 된 VM의 두 가지 VM이 포함됩니다. 이 두 솔루션은 Java HotSpot 런타임 환경 코드베이스를 공유하지만 클라이언트와 서버의 고유 한 성능 특성에 적합한 다른 컴파일러를 사용합니다. 이러한 차이점에는 컴파일 인라인 정책과 힙 기본값이 포함됩니다.

서버와 클라이언트 VM은 비슷하지만 서버 VM은 최고 작동 속도를 최대화하도록 특별히 조정되었습니다. 빠른 시작 시간 또는 더 작은 런타임 메모리 풋 프린트보다 가능한 가장 빠른 작동 속도가 필요한 장기 실행 서버 애플리케이션을 실행하기위한 것입니다.

클라이언트 VM 컴파일러는 이전 버전의 JDK에서 사용 된 Classic VM 및 JIT (Just-In-Time) 컴파일러 모두에 대한 업그레이드 역할을합니다. 클라이언트 VM은 응용 프로그램 및 애플릿에 향상된 런타임 성능을 제공합니다. Java HotSpot Client VM은 응용 프로그램 시작 시간과 메모리 공간을 줄이기 위해 특별히 조정되어 클라이언트 환경에 특히 적합합니다. 일반적으로 클라이언트 시스템은 GUI에 더 좋습니다.

따라서 실제 차이점은 컴파일러 수준에도 있습니다.

클라이언트 VM 컴파일러는 서버 VM에서 컴파일러가 수행하는보다 복잡한 여러 최적화를 실행하려고하지 않지만, 코드를 분석하고 컴파일하는 데 시간이 덜 걸립니다. 이는 클라이언트 VM이 더 빨리 시작될 수 있고 더 적은 메모리 공간을 필요로한다는 것을 의미합니다.

서버 VM에는 C ++ 컴파일러를 최적화하여 수행되는 동일한 유형의 최적화뿐만 아니라 가상 메서드 호출을 통한 적극적인 인라이닝과 같은 기존 컴파일러로는 수행 할 수없는 일부 최적화를 지원하는 고급 적응 형 컴파일러가 포함되어 있습니다. 이것은 정적 컴파일러에 비해 경쟁력과 성능상의 이점입니다. 적응 형 최적화 기술은 접근 방식이 매우 유연하며 일반적으로 고급 정적 분석 및 컴파일 기술을 능가합니다.

참고 : jdk6 업데이트 10 릴리스 ( 업데이트 릴리스 노트 : 1.6.0_10의 변경 사항 참조 )는 시작 시간을 개선하려고 시도했지만 핫스팟 옵션과는 다른 이유로 훨씬 작은 커널로 다르게 패키지되었습니다.


G. Demecki 는 64 비트 버전의 JDK에서는이 옵션이 몇 년 동안 무시 된다는 의견에서 지적합니다 -client. Windows 명령
참조 :java

-client

Java HotSpot 클라이언트 VM을 선택합니다.
64 비트 가능 JDK는 현재이 옵션을 무시하고 대신 Java Hotspot Server VM을 사용합니다 .


답변

이전 버전의 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 공간 사용량을 실시간으로 모니터링 할 수 있습니다 .


답변

-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

서버 시스템을보다 적극적으로 최적화하면 아무런 조치도 수행하지 않는다는 것을 이해하면서 루프를 제거하십시오!

참고


답변

방금 주목 한 한 가지 차이점은 “클라이언트”모드에서 JVM이 실제로 사용되지 않은 일부 메모리를 운영 체제에 다시 제공하는 것처럼 보이지만 “서버”모드를 사용하면 JVM이 메모리를 가져 오면 메모리를 제공하지 않습니다. 뒤. 어쨌든 Java6을 사용하여 Solaris에 나타나는 방법 ( prstat -Z프로세스에 할당 된 메모리 양을 보는 데 사용 ).


답변

Oracle 온라인 설명서는 Java SE 7에 대한 정보를 제공합니다.

자바 – 자바 응용 프로그램 실행 프로그램의 Windows 용 페이지에서 -client옵션은 64 비트 JDK에서 무시됩니다 :

Java HotSpot Client VM을 선택하십시오. 64 비트 가능 jdk는 현재이 옵션을 무시하고 대신 Java HotSpot Server VM을 사용합니다.

그러나 (사물을 흥미롭게 만들기 위해) 아래 -server에 나와 있습니다.

Java HotSpot Server VM을 선택하십시오. 64 비트 가능 jdk에서는 Java HotSpot Server VM 만 지원되므로 -server 옵션이 내재되어 있습니다. 향후 릴리스에서 변경 될 수 있습니다.

서버 클래스 머신 검출 페이지는 VM이 OS와 아키텍처에 의해 선택되는 정보를 제공합니다.

JDK 6에 이것이 얼마나 적용되는지 모르겠습니다.


답변

Goetz에서-실제로 Java 동시성 :

  1. 디버깅 팁 : 서버 애플리케이션의 -server경우 개발 및 테스트를 위해 JVM을 호출 할 때 항상 JVM 명령 행 스위치를 지정해야합니다 . 서버 JVM은 클라이언트 JVM보다 더 많은 최적화를 수행합니다 (예 : 루프에서 수정되지 않은 루프에서 변수를 올리는 것). 개발 환경 (클라이언트 JVM)에서 작동하는 것처럼 보이는 코드는 배포 환경 (서버 JVM)에서 중단 될 수 있습니다. 예를 들어, 목록 3.4에서 변수를 잠들게하는 변수를 “잠재적 인”것으로 선언하는 것을 잊어 버린 경우 , 서버 JVM은 루프에서 테스트를 끌어 올릴 수 있지만 (무한 루프로 전환) 클라이언트 JVM은 그렇지 않습니다 . 개발 과정에서 나타나는 무한 루프는 생산 과정에서만 나타나는 무한 루프보다 훨씬 저렴합니다.

Listing 3.4. 양 세기.


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

나의 강조. YMMV


답변

IIRC 서버 VM은 시작시 더 많은 핫스팟 최적화를 수행하므로 더 빠르게 실행되지만 시작하고 더 많은 메모리를 사용하는 데 시간이 조금 더 걸립니다. 클라이언트 VM은 대부분의 최적화를 지연시켜 더 빠른 시작을 허용합니다.

추가 편집 : 다음 은 Sun 의 정보 입니다. 매우 구체적이지는 않지만 몇 가지 아이디어를 제공합니다.