답변:
이것은 실제로 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을 사용합니다 .
-client
옵션은 몇 년 동안 무시됩니다.
이전 버전의 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
서버 시스템을보다 적극적으로 최적화하면 아무런 조치도 수행하지 않는다는 것을 이해하면서 루프를 제거하십시오!
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 동시성 :
- 디버깅 팁 : 서버 애플리케이션의
-server
경우 개발 및 테스트를 위해 JVM을 호출 할 때 항상 JVM 명령 행 스위치를 지정해야합니다 . 서버 JVM은 클라이언트 JVM보다 더 많은 최적화를 수행합니다 (예 : 루프에서 수정되지 않은 루프에서 변수를 올리는 것). 개발 환경 (클라이언트 JVM)에서 작동하는 것처럼 보이는 코드는 배포 환경 (서버 JVM)에서 중단 될 수 있습니다. 예를 들어, 목록 3.4에서 변수를 잠들게하는 변수를 "잠재적 인"것으로 선언하는 것을 잊어 버린 경우 , 서버 JVM은 루프에서 테스트를 끌어 올릴 수 있지만 (무한 루프로 전환) 클라이언트 JVM은 그렇지 않습니다 . 개발 과정에서 나타나는 무한 루프는 생산 과정에서만 나타나는 무한 루프보다 훨씬 저렴합니다.Listing 3.4. 양 세기.
volatile boolean asleep; ... while (!asleep) countSomeSheep();
나의 강조. YMMV
IIRC에는 가비지 수집 전략이 포함됩니다. 이론은 클라이언트와 서버가 수명이 짧은 객체의 관점에서 다르다는 것입니다. 이는 현대 GC 알고리즘에 중요합니다.
다음은 서버 모드에 대한 링크 입니다. 아아, 그들은 클라이언트 모드를 언급하지 않습니다.
다음은 GC에 대한 일반적인 링크 입니다. 이것은 더 기본적인 기사 입니다. 주소 -server와 -client 중 하나인지 확실하지 않지만 관련 자료입니다.
No Fluff Just Stuff에서 Ken Sipe와 Glenn Vandenburg는 이러한 종류의 일에 대해 큰 대화를 나눕니다.
2 사이의 시작 시간에 차이는 없었지만 "-server"(Solaris 서버, SunRays를 사용하여 응용 프로그램을 실행하는 모든 사람)의 응용 프로그램 성능이 최소한으로 향상되었습니다. 1.5 미만이었습니다.
지난번에 내가 이것을 보았을 때 (그리고 분명히 시간이 오래 걸렸다) 내가 발견 한 가장 큰 차이점은 가비지 수집에 있었다.
IIRC :
jvisualvm 도구를 사용하여 두 개의 Java VM, 하나의 클라이언트, 하나의 서버를 비교할 수 있다면 가비지 콜렉션의 빈도와 효과 및 세대 수에 차이가 있어야합니다.
차이점을 잘 보여주는 한 쌍의 스크린 샷이 있었지만 서버 VM 만 구현하는 64 비트 JVM이 있으므로 재현 할 수 없습니다. (그리고 내 시스템에서 32 비트 버전을 다운로드하고 얽매는 것도 귀찮게 할 수 없습니다.)
이것은 더 이상 사실이 아닌 것 같습니다. 서버와 클라이언트 VM이 모두있는 Windows에서 일부 코드를 실행하려고 시도했지만 둘 다 동일한 세대 모델을 얻는 것 같습니다 ...
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 버전에서는 프레임 크기가 다소 높다는 토론이 있습니다. 응용 프로그램의 동작에 따라 런타임에 실제 차이를 측정 할 수 있다고 믿습니다.