“Java -server” ve “java -client” arasındaki gerçek farklılıklar?


394

"Java -server" ve "java -client" arasında gerçek bir pratik fark var mı?

Sun'ın sitesinde bulabileceğim tek şey belirsiz

msgstr "-server yavaş başlar ancak daha hızlı çalışmalıdır".

Gerçek farklar nelerdir? (Şu anda JDK 1.6.0_07 kullanılıyor.)

Yanıtlar:


368

Bu gerçekten HotSpot ve istemci ve sunucu yapılandırması arasında farklılık gösteren varsayılan seçenek değerlerine ( Java HotSpot VM Seçenekleri ) bağlıdır.

Teknik belgenin 2. Bölümünden ( Java HotSpot Performans Motoru Mimarisi ):

JDK, VM'nin iki çeşidi içerir - bir istemci tarafı teklifi ve sunucu uygulamaları için ayarlanmış bir VM. Bu iki çözüm Java HotSpot çalışma zamanı ortam kodu tabanını paylaşır, ancak istemcilerin ve sunucuların benzersiz performans özelliklerine uygun farklı derleyiciler kullanır. Bu farklılıklar, derleme satır içi ilkesi ve yığın varsayılanlarını içerir.

Sunucu ve İstemci VM'leri benzer olsa da, Sunucu VM'si en yüksek çalışma hızını en üst düzeye çıkarmak için özel olarak ayarlanmıştır. Mümkün olan en hızlı çalışma hızına hızlı bir başlangıç ​​süresinden veya daha küçük çalışma zamanı bellek ayak izinden daha fazlasını gerektiren uzun süreli sunucu uygulamalarını yürütmek için tasarlanmıştır.

İstemci VM derleyicisi, hem Klasik VM hem de JDK'nın önceki sürümleri tarafından kullanılan tam zamanında (JIT) derleyiciler için yükseltme görevi görür. İstemci VM, uygulamalar ve uygulamalar için geliştirilmiş çalışma süresi performansı sunar. Java HotSpot Client VM, uygulama başlatma süresini ve bellek kapladığı alanı azaltmak için özel olarak ayarlanmıştır, bu da özellikle istemci ortamları için çok uygundur. Genel olarak, istemci sistemi GUI'ler için daha iyidir.

Yani gerçek fark derleyici seviyesinde:

İstemci VM derleyicisi, Sunucu VM'sinde derleyici tarafından gerçekleştirilen daha karmaşık optimizasyonların çoğunu yürütmeye çalışmaz, ancak karşılığında bir kod parçasını analiz etmek ve derlemek için daha az zaman gerektirir. Bu, İstemci VM'nin daha hızlı başlayabileceği ve daha az bellek alanı gerektirdiği anlamına gelir.

Sunucu VM'si, C ++ derleyicilerini optimize ederek gerçekleştirilen aynı optimizasyon türlerinin çoğunu ve sanal yöntem çağrılarında agresif satırlama gibi geleneksel derleyiciler tarafından gerçekleştirilemeyen bazı optimizasyonları destekleyen gelişmiş bir uyarlanabilir derleyici içerir. Bu, statik derleyicilere göre rekabetçi ve performans avantajıdır. Uyarlanabilir optimizasyon teknolojisi yaklaşımında çok esnektir ve tipik olarak gelişmiş statik analiz ve derleme tekniklerinden bile daha iyi performans gösterir.

Not: jdk6 10 güncellemesi (bkz. Güncelleme Sürüm Notları: 1.6.0_10'daki değişiklikler ), başlatma süresini iyileştirmeye çalıştı, ancak etkin nokta seçeneklerinden farklı bir nedenden dolayı, çok daha küçük bir çekirdekle farklı şekilde paketlendi.


G. Demecki işaret açıklamalarda bulunan JDK 64 bit sürümlerinde, -clientseçenek yıllarca göz ardı edilir. Windows komutuna
bakın :java

-client

Java HotSpot İstemci VM'sini seçer.
64 bit özellikli bir JDK şu anda bu seçeneği yoksayar ve bunun yerine Java Hotspot Server VM'sini kullanır .


7
jdk6 güncellemesi 10 ve sonrası, çalışma zamanı kitaplıklarını bellekte tutan bir arka plan işlemine sahiptir ve yeni işlemler için hepsini isteğe bağlı olarak sayfalamaktan çok daha hızlı başlatma sağlar.
Thorbjørn Ravn Andersen

1
Müşteri vm de agresif bir şekilde inline düşündüm, oh iyi.
Thorbjørn Ravn Andersen

1
Bu cevabın güncellenmesi gerektiğini düşünüyorum . Çünkü JDK'nın 64 bit sürümlerinde -clientseçenek yıllarca yok sayılır.
G. Demecki

@ G.Demecki Elbette: Bu seçeneğin eski veya yok sayıldığını belgeleyen bir bağlantınız var mı?
VonC

1
Elbette. İşte Windows için Java 7 için bazı belgeler . Şaşırtıcı bir şekilde, benzer bir bilgi Java 6 belgelerinde de bulunabilir .
G. Demecki

90

Java'nın eski sürümlerindeki en görünür ani fark, -clientbir -serveruygulamanın aksine a'ya ayrılan bellek olacaktır . Örneğin, Linux sistemimde:

$ 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"

varsayılan olarak -server, ama -clientben seçeneği ile :

$ 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"

bu nedenle -serverbellek sınırlarının çoğu ve ilk tahsisler bu javasürüm için çok daha yüksektir .

Ancak bu değerler mimarinin, işletim sisteminin ve jvm sürümünün farklı kombinasyonları için değişebilir. Jvm'nin son sürümleri bayrakları kaldırmış ve sunucu ile istemci arasındaki ayrımların çoğunu yeniden taşımıştır.

Eğer bir çalışan tüm ayrıntılarını görmek olduğu da unutmayın jvmkullanarak jvisualvm. Bu, JAVA_OPTSkomut satırı seçeneklerini değiştiren komut dosyaları ayarlayan veya kullanan kullanıcılarınız veya modülleriniz varsa kullanışlıdır . Bu, gerçek zamanlı olarak yığın ve permgen alanı kullanımını diğer birçok istatistikle birlikte izlemenizi sağlar.


2
CentOS 7 [Java (TM) SE Çalışma Zamanı Ortamı (build 1.7.0_79-b15) Java HotSpot (TM) 64-Bit Sunucu VM'deki java sürümü "1.7.0_79" için sunucu ve istemci modlarında aynı numaraları veriyor ]
Basil Musa

4
Bu yüzden cevabı verdim. Değerlerle ilgili değil, herhangi bir zamanda herkesin kendi jvm sürümünün cevabını bulmasını sağlamakla ilgili.
Mark Booth

33

-client ve -server sistemleri farklı ikili dosyalardır. Bunlar aslında aynı çalışma zamanı sistemine arabirim oluşturan iki farklı derleyicidir (JIT). İstemci sistemi, hızlı başlatma süreleri veya küçük ayak izleri gerektiren uygulamalar için en uygunudur, sunucu sistemi genel performansın en önemli olduğu uygulamalar için en uygunudur. Genel olarak istemci sistemi GUI'ler gibi etkileşimli uygulamalar için daha uygundur

resim açıklamasını buraya girin

Her iki anahtarla aşağıdaki kodu çalıştırıyoruz:

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

Not: Kod yalnızca bir kez derlenmiştir! Her iki koşuda da sınıflar aynı!

-Client:
java.exe -client -classpath ile C: \ mywork \ classes com.blogspot.sdoulger.LoopTest
Harcanan zaman: 766

-Server:
java.exe -server -classpath ile C: \ mywork \ classes com.blogspot.sdoulger.LoopTest
Harcanan zaman: 0

Sunucu sisteminin daha agresif optimizasyonu, herhangi bir eylem gerçekleştirmediğini anladığı için döngüyü kaldırın!

Referans


33

Fark ettiğim bir fark, "istemci" modunda, JVM'nin aslında işletim sistemine bazı kullanılmamış bellek verdiği, "sunucu" modunda ise, JVM belleği yakaladığında, vermediği geri. Yine de Solaris'te Java6 ile nasıl göründüğü ( prstat -Zbir işleme ayrılan bellek miktarını görmek için kullanarak ).


22

Oracle'ın çevrimiçi belgeleri Java SE 7 için bazı bilgiler sağlar.

Açık java - Java uygulaması başlatıcısı Windows için sayfanın -clientseçenek 64-bit JDK göz ardı edilir:

Java HotSpot İstemci VM'sini seçin. 64-bit özellikli bir jdk şu anda bu seçeneği yoksayar ve bunun yerine Java HotSpot Sunucu VM'sini kullanır.

Ancak (işleri ilginç hale getirmek için) altında -server:

Java HotSpot Sunucusu VM'sini seçin. 64-bit özellikli bir jdk'de sadece Java HotSpot Sunucu VM'si desteklenir, böylece -server seçeneği örtük olur. Bu, gelecekteki bir sürümde değişime tabidir.

Sunucu Sınıfı Makinesi Algılama sayfa VM OS ve mimarisinden seçildiği hakkında bilgi verir.

Bunun ne kadarının JDK 6 için geçerli olduğunu bilmiyorum.


2
Teşekkürler, ben JDK7 üzerinde bir istemci / jvm.dll görmedim nasıl merak ediyordum
Archimedes Trajano

16

Goetz'den - Uygulamada Java Eşzamanlılığı:

  1. Hata ayıklama ipucu: Sunucu uygulamaları için, -serverJVM'yi çağırırken geliştirme ve test için bile her zaman JVM komut satırı anahtarını belirttiğinizden emin olun . Sunucu JVM, döngüde değiştirilmeyen bir döngüden değişkenleri kaldırma gibi istemci JVM'den daha fazla optimizasyon gerçekleştirir; geliştirme ortamında (istemci JVM) çalışıyor gibi görünen kod dağıtım ortamında (sunucu JVM) bozulabilir. Örneğin, Değişken Listeleme 3.4'te değişken olarak uykuda olduğunu bildirmeyi “unutmuş olsaydık” , sunucu JVM testi döngüden kaldırabilir (sonsuz döngüye çevirebilir), ancak istemci JVM istemezdi . Gelişmede ortaya çıkan sonsuz bir döngü, sadece üretimde ortaya çıkandan çok daha az maliyetlidir.

Liste 3.4. Koyun saymak.

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

Vurgu. YMMV


15

IIRC sunucu VM başlangıçta daha fazla etkin nokta optimizasyonu yapar, böylece daha hızlı çalışır, ancak başlatılması biraz daha uzun sürer ve daha fazla bellek kullanır. İstemci VM, daha hızlı başlatma için optimizasyonun çoğunu savunur.

Eklemek için düzenleyin: İşte Sun'ın bazı bilgileri , çok spesifik değil ama size bazı fikirler verecektir.


5

IIRC, çöp toplama stratejilerini içerir. Teori, bir istemci ve sunucunun modern GC algoritmaları için önemli olan kısa ömürlü nesneler açısından farklı olacağıdır.

İşte sunucu modunda bir bağlantı . Ne yazık ki, müşteri modundan bahsetmiyorlar.

Genel olarak GC üzerinde çok kapsamlı bir bağlantı ; bu daha temel bir makale . Her iki adres -server vs -client olup olmadığından emin değilim ancak bu ilgili bir materyal.

No Fluff Just Stuff'da hem Ken Sipe hem de Glenn Vandenburg bu tür şeyler hakkında harika konuşmalar yapıyor.


3

Ben 2 arasında başlangıç ​​zamanı herhangi bir fark fark ettim, ama "-server" (Solaris sunucusu, uygulamayı çalıştırmak için SunRays kullanan herkes) ile uygulama performansında çok az bir iyileşme saat. Bu 1.5'in altındaydı.


6
Programınızın ne yaptığına bağlıdır. Aynı şeyi tekrar tekrar yapan bazı işlemci yoğun uygulamalar için, -server ile büyük (10x'e kadar) iyileştirmeler fark ettim .
Dan Dyer

1
Dan, buna referansın var mı? Daha fazla araştırmak istiyorum.
Thorbjørn Ravn Andersen

1
Sunflow'u sunucu VM ile çalıştırmak istemciden çok daha hızlıdır. sunflow.sourceforge.net
John

1

Son kez bu bir göz vardı, (ve kuşkusuz bir süre geri oldu) fark büyük fark çöp toplama oldu.

IIRC:

  • Sunucu yığın VM'si, İstemci VM'den farklı sayıda nesile ve farklı bir çöp toplama algoritmasına sahiptir. Bu artık doğru olmayabilir
  • Sunucu VM belleği tahsis eder ve işletim sistemine bırakmaz
  • Sunucu VM'si daha gelişmiş optimizasyon algoritmaları kullanacak ve bu nedenle optimizasyon için daha fazla zaman ve bellek gereksinimi olacaktır

Jvisualvm aracını kullanarak iki java VM'si , bir istemci, bir sunucu karşılaştırabiliyorsanız , çöp toplama sıklığı ve etkisi ile nesillerin sayısında bir fark görmelisiniz.

Farkı gerçekten gösteren bir çift ekran görüntüsü vardı, ancak yalnızca sunucu VM'sini uygulayan 64 bit JVM'ye sahip olduğum için çoğaltılamıyorum. (Ve 32 bit sürümünü sistemime de indirip rahatsız edemiyorum.)

Bu artık böyle görünmüyor, hem sunucu hem de istemci VM'leri ile pencerelerde bazı kod çalıştırmayı denedikten sonra, her ikisi için de aynı nesil modeli alıyor gibiyim ...


1

1.4'ten 1.7'ye ("1.7.0_55") sürüm geçişi yaparken. Burada gözlemlediğimiz şey, istemci ve sunucu modunda heapsize | permsize | ThreadStackSize parametrelerine atanan varsayılan değerlerde böyle bir fark yoktur.

Bu arada, ( http://www.oracle.com/technetwork/java/ergo5-140223.html ). Bu, yukarıdaki linkten alınan snippet'tir.

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'de daha yüksek, Open JDK forumundan geçerken 1.7 versiyonunda kare boyutunun biraz daha yüksek olduğunu belirten tartışmalar var. Uygulamanızdaki davranışınıza göre çalışma zamanında gerçek farkın ölçülebileceğine inanılmaktadır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.