java "जावा-सर्वर" और "जावा-क्लाइंट" के बीच वास्तविक अंतर?




jvm jvm-hotspot (9)

क्या "जावा-सर्वर" और "जावा-क्लाइंट" के बीच कोई वास्तविक व्यावहारिक अंतर है? मैं सूर्य की साइट पर जो कुछ भी पा सकता हूं वह एक अस्पष्ट है "-सर्वर धीमा शुरू होता है लेकिन तेजी से चलना चाहिए"। वास्तविक मतभेद क्या हैं? (वर्तमान में जेडीके 1.6.0_07 का उपयोग करना।)


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

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

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

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


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

IIRC:

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

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

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

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


गोएट्ज़ से - प्रैक्टिस में जावा कंसुरेंसी:

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

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

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

मेरा जोर YMMV


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


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

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

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

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

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

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

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

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

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

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

-client

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


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


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 संस्करण में कुछ हद तक अधिक है। ऐसा माना जाता है कि आपके आवेदन के व्यवहार के आधार पर रन टाइम पर मापने के लिए वास्तविक अंतर संभव हो सकता है


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

जावा पर - विंडोज़ के लिए जावा एप्लिकेशन लॉन्चर पेज, -client विकल्प 64-बिट जेडीके में अनदेखा किया गया है:

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

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

जावा हॉटस्पॉट सर्वर वीएम का चयन करें। एक 64-बिट सक्षम जेडीके पर केवल जावा हॉटस्पॉट सर्वर वीएम समर्थित है ताकि सर्वर विकल्प लागू हो। यह भविष्य की रिलीज में बदलाव के अधीन है।

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

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


जावा के पुराने संस्करणों में सबसे अधिक तत्काल तत्काल अंतर एक- -server अनुप्रयोग के विपरीत ए- -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 डिफ़ॉल्ट है, लेकिन -server विकल्प के साथ मुझे मिलता है:

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

इसलिए इस java संस्करण के लिए अधिकांश स्मृति सीमाएं और आरंभिक आवंटन बहुत अधिक हैं।

हालांकि ये मान आर्किटेक्चर, ऑपरेटिंग सिस्टम और जेवीएम संस्करण के विभिन्न संयोजनों के लिए बदल सकते हैं। जेवीएम के हाल के संस्करणों ने झंडे हटा दिए हैं और सर्वर और क्लाइंट के बीच कई भेदों को फिर से स्थानांतरित कर दिया है।

यह भी याद रखें कि आप jvisualvm का उपयोग कर चल रहे jvisualvm सभी विवरण देख सकते हैं। यह उपयोगी है यदि आपके पास ऐसे उपयोगकर्ता हैं जो मॉड्यूल या मॉड्यूल जो JAVA_OPTS सेट करते हैं या स्क्रिप्ट का उपयोग करते हैं जो कमांड लाइन विकल्प बदलते हैं। यह आपको कई अन्य आंकड़ों के साथ वास्तविक समय में, ढेर और परमजन अंतरिक्ष उपयोग की निगरानी भी करेगा।







jvm-hotspot