"जावा-रक्षक" और "जावा-मूल" के बीच वास्तविक अंतर?


394

क्या "जावा-सेवर" और "जावा-क्लेयर" के बीच कोई वास्तविक व्यावहारिक अंतर है?

मैं सूर्य की साइट पर पा सकते हैं एक अस्पष्ट है

"-सर्वर धीमा शुरू होता है, लेकिन तेज चलना चाहिए"।

असली अंतर क्या हैं? (वर्तमान में JDK 1.6.0_07 का उपयोग कर।)

जवाबों:


368

यह वास्तव में हॉटस्पॉट और डिफ़ॉल्ट विकल्प मूल्यों ( जावा हॉटस्पॉट वीएम विकल्प ) से जुड़ा हुआ है जो क्लाइंट और सर्वर कॉन्फ़िगरेशन के बीच भिन्न हैं।

से अध्याय 2 श्वेतपत्र (के जावा हॉटस्पॉट प्रदर्शन इंजन आर्किटेक्चर ):

JDK में VM के दो फ्लेवर्स शामिल हैं - क्लाइंट-साइड ऑफ़र, और सर्वर अनुप्रयोगों के लिए VM ट्यून। ये दो समाधान जावा हॉटस्पॉट रनटाइम पर्यावरण कोड आधार साझा करते हैं, लेकिन अलग-अलग संकलक का उपयोग करते हैं जो क्लाइंट और सर्वर के विशिष्ट अद्वितीय प्रदर्शन विशेषताओं के अनुकूल हैं। इन अंतरों में संकलन नीति और ढेर चूक शामिल हैं।

यद्यपि सर्वर और क्लाइंट VM समान हैं, सर्वर VM को विशेष रूप से चोटी ऑपरेटिंग गति को अधिकतम करने के लिए ट्यून किया गया है। यह लंबे समय तक चलने वाले सर्वर अनुप्रयोगों को निष्पादित करने के लिए है, जिसमें तेज शुरुआत समय या छोटे रनटाइम मेमोरी फुटप्रिंट की तुलना में सबसे तेज संभव ऑपरेटिंग गति की आवश्यकता होती है।

क्लाइंट वीएम कंपाइलर क्लासिक वीएम और जेडीके के पिछले संस्करणों द्वारा उपयोग किए जाने वाले जस्ट-इन-टाइम (जेआईटी) कंपाइलरों के लिए एक अपग्रेड के रूप में कार्य करता है। क्लाइंट वीएम अनुप्रयोगों और एप्लेट्स के लिए बेहतर रन समय प्रदर्शन प्रदान करता है। जावा हॉटस्पॉट क्लाइंट वीएम को विशेष रूप से एप्लिकेशन स्टार्ट-अप समय और मेमोरी फ़ुटप्रिंट को कम करने के लिए ट्यून किया गया है, जिससे यह क्लाइंट वातावरण के लिए विशेष रूप से अनुकूल है। सामान्य तौर पर, GUI के लिए क्लाइंट सिस्टम बेहतर है।

तो वास्तविक अंतर संकलक स्तर पर भी है:

क्लाइंट वीएम कंपाइलर सर्वर वीएम में कंपाइलर द्वारा किए गए कई अधिक जटिल अनुकूलन को निष्पादित करने का प्रयास नहीं करता है, लेकिन बदले में, कोड के एक टुकड़े का विश्लेषण और संकलन करने के लिए कम समय की आवश्यकता होती है। इसका मतलब है कि क्लाइंट वीएम तेजी से शुरू हो सकता है और इसके लिए छोटे मेमोरी फुटप्रिंट की आवश्यकता होती है।

सर्वर VM में एक उन्नत अनुकूली संकलक होता है जो C ++ संकलक के अनुकूलन द्वारा किए गए कई प्रकार के अनुकूलन का समर्थन करता है, साथ ही साथ कुछ अनुकूलन जो पारंपरिक संकलक द्वारा नहीं किए जा सकते हैं, जैसे कि वर्चुअल विधि इनवॉइस में आक्रामक इनलाइनिंग। यह स्थिर संकलक पर एक प्रतिस्पर्धी और प्रदर्शन लाभ है। अनुकूली अनुकूलन तकनीक अपने दृष्टिकोण में बहुत लचीली है, और आमतौर पर उन्नत स्थैतिक विश्लेषण और संकलन तकनीकों को बेहतर बनाती है।

नोट: jdk6 अपडेट 10 की रिलीज़ ( अपडेट रिलीज़ नोट देखें : 1.6.0_10 में परिवर्तन ) ने स्टार्टअप समय में सुधार करने की कोशिश की, लेकिन हॉटस्पॉट विकल्पों की तुलना में एक अलग कारण के लिए, बहुत छोटे कर्नेल के साथ अलग-अलग पैक किया गया।


जी। डेमेकी टिप्पणियों में बताते हैं कि जेडीके के 64-बिट संस्करणों में -clientकई वर्षों के लिए विकल्प को नजरअंदाज किया जाता है।
देखें विंडोज javaकमांड :

-client

जावा हॉटस्पॉट क्लाइंट वीएम का चयन करता है।
64-बिट सक्षम JDK वर्तमान में इस विकल्प को अनदेखा करता है और इसके बजाय जावा हॉटस्पॉट सर्वर VM का उपयोग करता है


7
jdk6 अपडेट 10 और उसके बाद की पृष्ठभूमि की प्रक्रिया है जो स्मृति में रनटाइम लाइब्रेरीज़ को रखते हुए नई प्रक्रियाओं के लिए बहुत तेज़ स्टार्टअप की अनुमति देती है, क्योंकि यह सभी मांग पर है।
थोरबजर्न रेवन एंडरसन

1
सोचा ग्राहक vm भी आक्रामक तरीके से, ओह अच्छी तरह से इनलेट।
Thorbjørn रावन एंडरसन

1
मुझे लगता है कि इस उत्तर को अद्यतन किया जाना चाहिए। क्योंकि JDK के 64-बिट संस्करणों पर -clientविकल्प को कई सालों तक नजरअंदाज किया जाता है।
जी डेमेकी

@ G.Demecki ज़रूर: क्या आपके पास एक दस्तावेज है जो इस विकल्प को अप्रचलित या अनदेखा कर रहा है?
वॉन

1
ज़रूर। यहाँ विंडोज के लिए जावा 7 के लिए कुछ डॉक्यूमेंटेशन है । और आश्चर्यजनक रूप से एक समान जानकारी जावा 6 प्रलेखन में भी पाई जा सकती है ।
जी डेमेकी

90

जावा के पुराने संस्करणों में सबसे अधिक दिखाई देने वाला तात्कालिक अंतर -clientएक -serverअनुप्रयोग के विपरीत स्मृति को आवंटित किया जाएगा । उदाहरण के लिए, मेरे लिनक्स सिस्टम पर, मुझे मिलता है:

$ 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स्क्रिप्ट्स सेट या उपयोग करते हैं जो कमांड लाइन विकल्प बदलते हैं। यह आपको वास्तविक समय में, ढेर और अन्य आँकड़े के साथ-साथ ढेर और पर्मगेन अंतरिक्ष उपयोग की निगरानी करने देगा ।


2
यह मुझे CentOS 7 [जावा (TM) एसई रनटाइम एनवायरनमेंट (1.7.0_79-b15 का निर्माण) जावा हॉटस्पॉट (TM) 64-बिट सर्वर वीएम पर जावा संस्करण "1.7.0_79" के लिए एक ही नंबर देता है। ]
तुलसी मूसा

4
यही कारण है कि मैंने उत्तर प्रदान किया। यह मूल्यों के बारे में नहीं है, यह किसी भी समय किसी को भी सक्षम करने के बारे में है, अपने विशिष्ट jvm संस्करण के लिए उत्तर खोजने के लिए।
मार्क बूथ

33

-client और -server सिस्टम अलग-अलग बायनेरिज़ हैं। वे अनिवार्य रूप से दो अलग-अलग संकलक (जेआईटी) हैं जो एक ही रनटाइम सिस्टम में हस्तक्षेप करते हैं। क्लाइंट सिस्टम उन अनुप्रयोगों के लिए इष्टतम है, जिन्हें तेजी से स्टार्टअप समय या छोटे पैरों के निशान की आवश्यकता होती है, सर्वर सिस्टम उन अनुप्रयोगों के लिए इष्टतम है जहां समग्र प्रदर्शन सबसे महत्वपूर्ण है। सामान्य रूप से क्लाइंट सिस्टम इंटरैक्टिव अनुप्रयोगों जैसे GUIs के लिए बेहतर अनुकूल है

यहां छवि विवरण दर्ज करें

हम दोनों स्विच के साथ निम्नलिखित कोड चलाते हैं:

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

साथ-साथ:
java.exe -server -classpath C: \ mywork \ classes com.blogspot.sdoulger.LoopTest
समय व्यतीत: 0

ऐसा लगता है कि सर्वर सिस्टम के अधिक आक्रामक अनुकूलन, लूप को हटा दें क्योंकि यह समझता है कि यह कोई कार्रवाई नहीं करता है!

संदर्भ


33

एक अंतर जो मैंने अभी देखा है वह यह है कि "क्लाइंट" मोड में, ऐसा लगता है कि जेवीएम वास्तव में कुछ अप्रयुक्त मेमोरी को ऑपरेटिंग सिस्टम को वापस देता है, जबकि "सर्वर" मोड के साथ, एक बार जेवीएम मेमोरी को पकड़ लेता है, तो यह इसे नहीं देगा। वापस। वैसे भी यह जावा 6 के साथ सोलारिस पर कैसे प्रकट होता है ( prstat -Zकिसी प्रक्रिया को आवंटित स्मृति की मात्रा देखने के लिए)।


22

ओरेकल का ऑनलाइन प्रलेखन जावा एसई 7 के लिए कुछ जानकारी प्रदान करता है।

पर जावा - जावा आवेदन लांचर विंडोज के लिए पेज, -clientविकल्प के लिए एक 64-बिट JDK में नजरअंदाज कर दिया है:

जावा हॉटस्पॉट क्लाइंट वीएम का चयन करें। 64-बिट सक्षम jdk वर्तमान में इस विकल्प को अनदेखा करता है और इसके बजाय Java HotSpot Server VM का उपयोग करता है।

हालांकि, चीजों को दिलचस्प बनाने के लिए), इसके तहत -serverकहा गया है:

जावा हॉटस्पॉट सर्वर वीएम का चयन करें। 64-बिट सक्षम jdk पर केवल जावा हॉटस्पॉट सर्वर VM समर्थित है, इसलिए -server विकल्प निहित है। यह भविष्य की रिलीज़ में परिवर्तन के अधीन है।

सर्वर-क्लास मशीन डिटेक्शन पेज जानकारी है जिस पर वीएम ओएस और स्थापत्य कला से चुना जाता है देता है।

मुझे नहीं पता कि यह JDK 6 पर कितना लागू होता है।


2
धन्यवाद, मैं सोच रहा था कि मैं कैसे JDK7 पर एक ग्राहक / jvm.dll नहीं देख रहा हूँ
आर्किमिडीज़

16

गेटेज़ से - व्यवहार में जावा कॉनएजेंसी:

  1. टिप डिबगिंग: सर्वर अनुप्रयोगों के लिए, हमेशा सुनिश्चित करें कि -serverजेवीएम को लागू करते समय जेवीएम कमांड लाइन स्विच को निर्दिष्ट करें , यहां तक ​​कि विकास और परीक्षण के लिए भी । सर्वर JVM क्लाइंट JVM की तुलना में अधिक अनुकूलन करता है, जैसे कि लूप से परिवर्तनशील चर जो लूप में संशोधित नहीं होते हैं; विकास पर्यावरण में काम करने के लिए प्रकट हो सकने वाला कोड (क्लाइंट JVM) परिनियोजन वातावरण (सर्वर JVM) में टूट सकता है। उदाहरण के लिए, क्या हमें 3.4 को सूचीबद्ध करने के लिए चर के रूप में सोते समय घोषित करने के लिए "भूल" गया था, सर्वर जेवीएम लूप से परीक्षण को बाहर निकाल सकता है (इसे अनंत लूप में बदल सकता है), लेकिन क्लाइंट जेवीएम नहीं होगा । एक अनंत लूप जो विकास में दिखाई देता है वह एक की तुलना में बहुत कम खर्चीला है जो केवल उत्पादन में दिखाता है।

लिस्टिंग 3.4। नींद लाने के लिए दिमागी कसरत करना।

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

मेरा जोर। YMMV


15

IIRC सर्वर VM स्टार्टअप पर अधिक हॉटस्पॉट अनुकूलन करता है इसलिए यह तेजी से चलता है लेकिन अधिक मेमोरी शुरू करने और उपयोग करने में थोड़ा अधिक समय लेता है। क्लाइंट वीएम तेजी से स्टार्टअप की अनुमति देने के लिए अधिकांश अनुकूलन का बचाव करता है।

जोड़ने के लिए संपादित करें: यहां सूर्य से कुछ जानकारी है, यह बहुत विशिष्ट नहीं है लेकिन आपको कुछ विचार देगा।


5

IIRC, इसमें कचरा संग्रहण रणनीति शामिल है। सिद्धांत यह है कि एक ग्राहक और सर्वर अल्पकालिक वस्तुओं के संदर्भ में भिन्न होंगे, जो आधुनिक जीसी एल्गोरिदम के लिए महत्वपूर्ण है।

यहाँ सर्वर मोड पर एक लिंक है। काश, वे क्लाइंट मोड का उल्लेख नहीं करते।

यहां जीसी पर सामान्य रूप से बहुत गहन लिंक है ; यह एक अधिक मूल लेख है । निश्चित नहीं है कि या तो एड्रेस-सेवर बनाम -क्विएंट लेकिन यह प्रासंगिक सामग्री है।

नो फुल जस्ट स्टफ में, केन साइप और ग्लेन वंडेनबर्ग दोनों इस तरह की चीजों पर बहुत अच्छी बातचीत करते हैं।


3

मैंने 2 के बीच स्टार्टअप समय में कोई अंतर नहीं देखा है, लेकिन "-server" (सोलारिस सर्वर, हर कोई ऐप चलाने के लिए SunRays का उपयोग करके) के साथ अनुप्रयोग के प्रदर्शन में बहुत कम सुधार देखा है। वह 1.5 से कम था।


6
निर्भर करता है कि आपका कार्यक्रम क्या कर रहा है। कुछ प्रोसेसर-गहन अनुप्रयोगों के लिए जो एक ही काम को बार-बार करते हैं, मैंने -वर के साथ भारी (10x तक) सुधारों पर ध्यान दिया है।
दान डायर

1
दान, क्या आपके पास इसका संदर्भ है? मैं आगे की जांच करना चाहता हूं।
थोरबजर्न रेवन एंडरसन

1
VM से सर्वर के साथ रनिंग सनफ़्लो क्लाइंट से तेज़ है। sunflow.sourceforge.net
जॉन

1

पिछली बार मैंने इस पर एक नज़र डाली थी, (और माना जाता है कि यह कुछ समय पहले था) सबसे बड़ा अंतर जो मैंने देखा था वह कचरा संग्रह में था।

IIRC:

  • सर्वर हीप VM क्लाइंट क्लायंट वीएम की तुलना में पीढ़ियों की एक अलग संख्या है, और एक अलग कचरा संग्रह एल्गोरिथ्म है। यह अब सच नहीं हो सकता है
  • सर्वर VM मेमोरी आवंटित करेगा और इसे OS पर रिलीज़ नहीं करेगा
  • सर्वर VM अधिक परिष्कृत अनुकूलन एल्गोरिदम का उपयोग करेगा, और इसलिए अनुकूलन के लिए बड़ा समय और मेमोरी आवश्यकताएं हैं

यदि आप दो जावा वीएम, एक ग्राहक, एक सर्वर की तुलना कर सकते हैं जो कि jvisualvm टूल का उपयोग कर रहा है, तो आपको कचरा संग्रह की आवृत्ति और प्रभाव में अंतर के साथ-साथ पीढ़ियों की संख्या में भी अंतर दिखाई देना चाहिए।

मेरे पास स्क्रीनशॉट की एक जोड़ी थी जो वास्तव में अच्छी तरह से अंतर दिखाती थी, लेकिन मैं पुन: पेश नहीं कर सकता क्योंकि मेरे पास 64 बिट जेवीएम है जो केवल सर्वर वीएम को लागू करता है। (और मैं अपने सिस्टम पर 32 बिट संस्करण को डाउनलोड करने और खराब करने के लिए परेशान नहीं हो सकता।)

यह अब मामला नहीं लगता है, दोनों सर्वर और क्लाइंट VMs के साथ खिड़कियों पर कुछ कोड चलाने की कोशिश की, मुझे लगता है कि दोनों के लिए एक ही पीढ़ी के मॉडल मिल रहे हैं ...


1

जब 1.4 से 1.7 ("1.7.0_55") संस्करण से माइग्रेशन कर रहे हैं। जिस चीज को हमने यहां देखा है, वह यह है कि डिफ़ॉल्ट मानों में ऐसा कोई अंतर नहीं है, जिसे ढेर किया गया है। permsize |

वैसे, ( 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

थ्रेडस्टैकसाइज 1.7 में अधिक है, ओपन जेडडीके फोरम से गुजरने के दौरान, चर्चाएं हैं कि कहा गया है कि फ्रेम का आकार 1.7 संस्करण में कुछ अधिक है। यह माना जाता है कि वास्तविक अंतर आपके आवेदन के व्यवहार के आधार पर रन टाइम को मापना संभव हो सकता है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.