문제

"Java -server"와 "Java -Client"사이에 실질적인 차이가 있습니까?

내가 Sun의 사이트에서 찾을 수있는 것은 모호한 것입니다.

"-서버는 느리게 시작하지만 더 빨리 실행해야합니다."

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

도움이 되었습니까?

해결책

이것은 실제로 연결되어 있습니다 핫스팟 그리고 기본값 옵션 값 (Java 핫스팟 VM 옵션) 클라이언트와 서버 구성이 다릅니다.

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

JDK에는 VM의 두 가지 맛 (클라이언트 측 제품)과 서버 애플리케이션을 위해 VM이 포함되어 있습니다. 이 두 솔루션은 Java Hotspot 런타임 환경 코드 기반을 공유하지만 클라이언트 및 서버의 고유 한 성능 특성에 적합한 다양한 컴파일러를 사용합니다. 이러한 차이점에는 정책을 수집하는 컴파일 및 힙 기본값이 포함됩니다.

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

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

따라서 실제 차이는 컴파일러 레벨에도 있습니다.

클라이언트 VM 컴파일러는 서버 VM의 컴파일러에서 수행하는보다 복잡한 최적화를 많이 실행하려고 시도하지 않지만 대가로 코드를 분석하고 컴파일하는 데 시간이 적습니다. 이는 클라이언트 VM이 더 빨리 시작할 수 있고 더 작은 메모리 풋 프린트가 필요하다는 것을 의미합니다.

Server VM에는 C ++ 컴파일러를 최적화하여 수행되는 동일한 유형의 최적화를 지원하는 고급 적응 형 컴파일러와 가상 메소드의 부정 관념에 대한 공격적인 인라인과 같은 기존 컴파일러가 수행 할 수없는 일부 최적화를 지원합니다. 이것은 정적 컴파일러에 비해 경쟁력 있고 성능 이점입니다. 적응 최적화 기술은 접근 방식이 매우 유연하며 일반적으로 고급 정적 분석 및 컴파일 기술을 능가합니다.

참고 : 릴리스 JDK6 업데이트 10 (보다 릴리스 노트 업데이트 : 1.6.0_10의 변경)는 시작 시간을 개선하려고 시도했지만 핫스팟 옵션과는 다른 이유가 훨씬 작은 커널과 다르게 포장됩니다.


G. Demecki 지적 의견에서 64 비트 버전의 JDK에서 -client 옵션은 수년 동안 무시됩니다.
보다 java 명령:

-client

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

다른 팁

이전 버전의 Java에서 가장 눈에 띄는 즉각적인 차이는 -client a -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 또는 명령 줄 옵션을 변경하는 스크립트를 사용하십시오. 이것은 또한 실시간으로 모니터링 할 수 있습니다. 더미 그리고 페름기 다른 많은 통계와 함께 공간 사용.

방금 알아 차린 한 가지 차이점은 "클라이언트"모드에서 JVM이 실제로 사용되지 않은 메모리를 운영 체제에 다시 제공하는 것처럼 보이지만 "서버"모드를 사용하면 JVM이 메모리를 잡으면주지 않으면주지 않을 것입니다. 뒤. 어쨌든 Java6과 함께 Solaris에 나타납니다 (사용 prstat -Z 프로세스에 할당 된 메모리의 양을보기 위해).

-Client 및 -server 시스템은 다른 바이너리입니다. 본질적으로 동일한 런타임 시스템에 인터페이스하는 두 가지 다른 컴파일러 (JIT)입니다. 클라이언트 시스템은 빠른 시작 시간 또는 작은 발자국이 필요한 애플리케이션에 최적이며 서버 시스템은 전체 성능이 가장 중요한 응용 프로그램에 최적입니다. 일반적으로 클라이언트 시스템은 GUIS와 같은 대화식 응용 프로그램에 더 적합합니다.

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

메모: 코드는 한 번만 컴파일되었습니다! 수업은 두 달리기에서 동일합니다!

-Client :
java.exe -clist -classpath c : mywork classment com.blogspot.sdoulger.looptest
소비 된 시간 : 766

-server :
java.exe -server -classpath c : mywork classe com.blogspot.sdoulger.looptest
소비 된 시간 : 0

서버 시스템을보다 공격적으로 최적화하면 작업이 수행되지 않는다는 것을 이해하기 때문에 루프를 제거하는 것 같습니다!

참조

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

Java - Java 응용 프로그램 런처 Windows 용 페이지, -client 옵션은 64 비트 JDK에서 무시됩니다.

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

그러나 (흥미로운 일을하기 위해) -server 그것은 말한다 :

Java Hotspot Server VM을 선택하십시오. 64 비트 유능한 JDK에서는 Java Hotspot Server VM 만 지원되므로 -server 옵션이 암시 적입니다. 이것은 향후 릴리스에서 변경 될 수 있습니다.

그만큼 서버 클래스 머신 감지 페이지는 OS 및 아키텍처에서 선택한 VM에 대한 정보를 제공합니다.

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

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

추가 할 편집 : 여기에 정보가 있습니다 태양으로부터, 그것은 그다지 구체적이지는 않지만 몇 가지 아이디어를 줄 것입니다.

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

  1. 디버깅 팁 : 서버 응용 프로그램의 경우 항상 -server JVM 명령 줄 스위치 JVM을 호출 할 때 개발 및 테스트조차도. 서버 JVM은 루프에서 수정되지 않은 루프에서 벗어난 변수와 같은 클라이언트 JVM보다 더 많은 최적화를 수행합니다. 개발 환경 (클라이언트 JVM)에서 작동하는 것으로 보이는 코드는 배포 환경 (서버 JVM)에서 중단 될 수 있습니다. 예를 들어, 우리는 목록 3.4에서 변수를 휘발성으로 선언하는 것을“잊어 버렸습니다”. 서버 jvm은 루프에서 테스트를 호에 올릴 수 있지만 (무한 루프로 전환) 클라이언트 JVM은 그렇지 않습니다.. 개발에 나타나는 무한 루프는 생산에만 나타나는 것보다 훨씬 저렴합니다.

목록 3.4. 양 세기.

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

내 강조. ymmv

IIRC, 그것은 쓰레기 수집 전략을 포함합니다. 이론은 클라이언트와 서버가 단기 객체 측면에서 다를 것이며, 이는 최신 GC 알고리즘에 중요합니다.

여기 링크가 있습니다 서버 모드에서. 아아, 그들은 클라이언트 모드를 언급하지 않습니다.

다음은 매우 철저한 링크입니다 일반적으로 GC에서; 이것은 더 기본적인 기사. 주소 -Server 대 -Client 중 하나인지 확실하지 않지만 이것은 관련 자료입니다.

Fluff Gust 물건에서 Ken Sipe와 Glenn Vandenburg는 이런 종류의 일에 대해 훌륭한 대화를합니다.

2 사이의 시작 시간의 차이는 눈치 채지 못했지만 "-server"(Solaris Server, Sunrays를 사용하여 앱을 실행하기 위해 모든 사람)를 사용하여 애플리케이션 성능이 매우 최소화되었습니다. 그것은 1.5 미만이었습니다.

지난번에 내가 이것을 살펴 보았을 때 (그리고 그것은 시간이 오래되었다) 내가 알아 차린 가장 큰 차이점은 쓰레기 수집에 있었다.

IIRC :

  • 서버 힙 VM은 클라이언트 VM과 다른 세대와 다른 쓰레기 수집 알고리즘이 다릅니다. 이것은 더 이상 사실이 아닐 수도 있습니다
  • 서버 VM은 메모리를 할당하여 OS에 해제하지 않습니다.
  • 서버 VM은보다 정교한 최적화 알고리즘을 사용하므로 최적화를위한 시간과 메모리 요구 사항이 더 커집니다.

두 개의 Java VM, 하나의 클라이언트, 하나의 서버를 사용하여 비교할 수있는 경우 jvisualvm 도구, 쓰레기 수집의 빈도와 효과와 세대의 수에 차이가 있습니다.

차이를 잘 보여주는 스크린 샷이 있었지만 서버 VM만을 구현하는 64 비트 JVM이 있으므로 재현 할 수 없습니다. (그리고 나는 내 시스템에서 32 비트 버전을 다운로드하고 정화하는 것을 귀찮게 할 수 없습니다.)

서버와 클라이언트 vms를 사용하여 Windows에서 일부 코드를 실행하려고 시도한 후에는 더 이상 그렇지 않은 것 같습니다.

1.4에서 1.7 ( "1.7.0_55") 버전을 수행 할 때, 여기서 관찰 한 것은 클라이언트 및 서버 모드에서 heapsize | 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 버전에서는 다소 높다는 논의가 있습니다. 응용 프로그램의 동작에 따라 실행 시간에 측정 할 수있는 실제 차이가 가능할 수 있다고 생각됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top