क्या "जावा-सेवर" और "जावा-क्लेयर" के बीच कोई वास्तविक व्यावहारिक अंतर है?
मैं सूर्य की साइट पर पा सकते हैं एक अस्पष्ट है
"-सर्वर धीमा शुरू होता है, लेकिन तेज चलना चाहिए"।
असली अंतर क्या हैं? (वर्तमान में JDK 1.6.0_07 का उपयोग कर।)
क्या "जावा-सेवर" और "जावा-क्लेयर" के बीच कोई वास्तविक व्यावहारिक अंतर है?
मैं सूर्य की साइट पर पा सकते हैं एक अस्पष्ट है
"-सर्वर धीमा शुरू होता है, लेकिन तेज चलना चाहिए"।
असली अंतर क्या हैं? (वर्तमान में JDK 1.6.0_07 का उपयोग कर।)
जवाबों:
यह वास्तव में हॉटस्पॉट और डिफ़ॉल्ट विकल्प मूल्यों ( जावा हॉटस्पॉट वीएम विकल्प ) से जुड़ा हुआ है जो क्लाइंट और सर्वर कॉन्फ़िगरेशन के बीच भिन्न हैं।
से अध्याय 2 श्वेतपत्र (के जावा हॉटस्पॉट प्रदर्शन इंजन आर्किटेक्चर ):
JDK में VM के दो फ्लेवर्स शामिल हैं - क्लाइंट-साइड ऑफ़र, और सर्वर अनुप्रयोगों के लिए VM ट्यून। ये दो समाधान जावा हॉटस्पॉट रनटाइम पर्यावरण कोड आधार साझा करते हैं, लेकिन अलग-अलग संकलक का उपयोग करते हैं जो क्लाइंट और सर्वर के विशिष्ट अद्वितीय प्रदर्शन विशेषताओं के अनुकूल हैं। इन अंतरों में संकलन नीति और ढेर चूक शामिल हैं।
यद्यपि सर्वर और क्लाइंट VM समान हैं, सर्वर VM को विशेष रूप से चोटी ऑपरेटिंग गति को अधिकतम करने के लिए ट्यून किया गया है। यह लंबे समय तक चलने वाले सर्वर अनुप्रयोगों को निष्पादित करने के लिए है, जिसमें तेज शुरुआत समय या छोटे रनटाइम मेमोरी फुटप्रिंट की तुलना में सबसे तेज संभव ऑपरेटिंग गति की आवश्यकता होती है।
क्लाइंट वीएम कंपाइलर क्लासिक वीएम और जेडीके के पिछले संस्करणों द्वारा उपयोग किए जाने वाले जस्ट-इन-टाइम (जेआईटी) कंपाइलरों के लिए एक अपग्रेड के रूप में कार्य करता है। क्लाइंट वीएम अनुप्रयोगों और एप्लेट्स के लिए बेहतर रन समय प्रदर्शन प्रदान करता है। जावा हॉटस्पॉट क्लाइंट वीएम को विशेष रूप से एप्लिकेशन स्टार्ट-अप समय और मेमोरी फ़ुटप्रिंट को कम करने के लिए ट्यून किया गया है, जिससे यह क्लाइंट वातावरण के लिए विशेष रूप से अनुकूल है। सामान्य तौर पर, GUI के लिए क्लाइंट सिस्टम बेहतर है।
तो वास्तविक अंतर संकलक स्तर पर भी है:
क्लाइंट वीएम कंपाइलर सर्वर वीएम में कंपाइलर द्वारा किए गए कई अधिक जटिल अनुकूलन को निष्पादित करने का प्रयास नहीं करता है, लेकिन बदले में, कोड के एक टुकड़े का विश्लेषण और संकलन करने के लिए कम समय की आवश्यकता होती है। इसका मतलब है कि क्लाइंट वीएम तेजी से शुरू हो सकता है और इसके लिए छोटे मेमोरी फुटप्रिंट की आवश्यकता होती है।
सर्वर VM में एक उन्नत अनुकूली संकलक होता है जो C ++ संकलक के अनुकूलन द्वारा किए गए कई प्रकार के अनुकूलन का समर्थन करता है, साथ ही साथ कुछ अनुकूलन जो पारंपरिक संकलक द्वारा नहीं किए जा सकते हैं, जैसे कि वर्चुअल विधि इनवॉइस में आक्रामक इनलाइनिंग। यह स्थिर संकलक पर एक प्रतिस्पर्धी और प्रदर्शन लाभ है। अनुकूली अनुकूलन तकनीक अपने दृष्टिकोण में बहुत लचीली है, और आमतौर पर उन्नत स्थैतिक विश्लेषण और संकलन तकनीकों को बेहतर बनाती है।
नोट: jdk6 अपडेट 10 की रिलीज़ ( अपडेट रिलीज़ नोट देखें : 1.6.0_10 में परिवर्तन ) ने स्टार्टअप समय में सुधार करने की कोशिश की, लेकिन हॉटस्पॉट विकल्पों की तुलना में एक अलग कारण के लिए, बहुत छोटे कर्नेल के साथ अलग-अलग पैक किया गया।
जी। डेमेकी टिप्पणियों में बताते हैं कि जेडीके के 64-बिट संस्करणों में -client
कई वर्षों के लिए विकल्प को नजरअंदाज किया जाता है।
देखें विंडोज java
कमांड :
-client
जावा हॉटस्पॉट क्लाइंट वीएम का चयन करता है।
64-बिट सक्षम JDK वर्तमान में इस विकल्प को अनदेखा करता है और इसके बजाय जावा हॉटस्पॉट सर्वर VM का उपयोग करता है ।
-client
विकल्प को कई सालों तक नजरअंदाज किया जाता है।
जावा के पुराने संस्करणों में सबसे अधिक दिखाई देने वाला तात्कालिक अंतर -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
स्क्रिप्ट्स सेट या उपयोग करते हैं जो कमांड लाइन विकल्प बदलते हैं। यह आपको वास्तविक समय में, ढेर और अन्य आँकड़े के साथ-साथ ढेर और पर्मगेन अंतरिक्ष उपयोग की निगरानी करने देगा ।
-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
ऐसा लगता है कि सर्वर सिस्टम के अधिक आक्रामक अनुकूलन, लूप को हटा दें क्योंकि यह समझता है कि यह कोई कार्रवाई नहीं करता है!
एक अंतर जो मैंने अभी देखा है वह यह है कि "क्लाइंट" मोड में, ऐसा लगता है कि जेवीएम वास्तव में कुछ अप्रयुक्त मेमोरी को ऑपरेटिंग सिस्टम को वापस देता है, जबकि "सर्वर" मोड के साथ, एक बार जेवीएम मेमोरी को पकड़ लेता है, तो यह इसे नहीं देगा। वापस। वैसे भी यह जावा 6 के साथ सोलारिस पर कैसे प्रकट होता है ( prstat -Z
किसी प्रक्रिया को आवंटित स्मृति की मात्रा देखने के लिए)।
ओरेकल का ऑनलाइन प्रलेखन जावा एसई 7 के लिए कुछ जानकारी प्रदान करता है।
पर जावा - जावा आवेदन लांचर विंडोज के लिए पेज, -client
विकल्प के लिए एक 64-बिट JDK में नजरअंदाज कर दिया है:
जावा हॉटस्पॉट क्लाइंट वीएम का चयन करें। 64-बिट सक्षम jdk वर्तमान में इस विकल्प को अनदेखा करता है और इसके बजाय Java HotSpot Server VM का उपयोग करता है।
हालांकि, चीजों को दिलचस्प बनाने के लिए), इसके तहत -server
कहा गया है:
जावा हॉटस्पॉट सर्वर वीएम का चयन करें। 64-बिट सक्षम jdk पर केवल जावा हॉटस्पॉट सर्वर VM समर्थित है, इसलिए -server विकल्प निहित है। यह भविष्य की रिलीज़ में परिवर्तन के अधीन है।
सर्वर-क्लास मशीन डिटेक्शन पेज जानकारी है जिस पर वीएम ओएस और स्थापत्य कला से चुना जाता है देता है।
मुझे नहीं पता कि यह JDK 6 पर कितना लागू होता है।
गेटेज़ से - व्यवहार में जावा कॉनएजेंसी:
- टिप डिबगिंग: सर्वर अनुप्रयोगों के लिए, हमेशा सुनिश्चित करें कि
-server
जेवीएम को लागू करते समय जेवीएम कमांड लाइन स्विच को निर्दिष्ट करें , यहां तक कि विकास और परीक्षण के लिए भी । सर्वर JVM क्लाइंट JVM की तुलना में अधिक अनुकूलन करता है, जैसे कि लूप से परिवर्तनशील चर जो लूप में संशोधित नहीं होते हैं; विकास पर्यावरण में काम करने के लिए प्रकट हो सकने वाला कोड (क्लाइंट JVM) परिनियोजन वातावरण (सर्वर JVM) में टूट सकता है। उदाहरण के लिए, क्या हमें 3.4 को सूचीबद्ध करने के लिए चर के रूप में सोते समय घोषित करने के लिए "भूल" गया था, सर्वर जेवीएम लूप से परीक्षण को बाहर निकाल सकता है (इसे अनंत लूप में बदल सकता है), लेकिन क्लाइंट जेवीएम नहीं होगा । एक अनंत लूप जो विकास में दिखाई देता है वह एक की तुलना में बहुत कम खर्चीला है जो केवल उत्पादन में दिखाता है।लिस्टिंग 3.4। नींद लाने के लिए दिमागी कसरत करना।
volatile boolean asleep; ... while (!asleep) countSomeSheep();
मेरा जोर। YMMV
IIRC सर्वर VM स्टार्टअप पर अधिक हॉटस्पॉट अनुकूलन करता है इसलिए यह तेजी से चलता है लेकिन अधिक मेमोरी शुरू करने और उपयोग करने में थोड़ा अधिक समय लेता है। क्लाइंट वीएम तेजी से स्टार्टअप की अनुमति देने के लिए अधिकांश अनुकूलन का बचाव करता है।
जोड़ने के लिए संपादित करें: यहां सूर्य से कुछ जानकारी है, यह बहुत विशिष्ट नहीं है लेकिन आपको कुछ विचार देगा।
IIRC, इसमें कचरा संग्रहण रणनीति शामिल है। सिद्धांत यह है कि एक ग्राहक और सर्वर अल्पकालिक वस्तुओं के संदर्भ में भिन्न होंगे, जो आधुनिक जीसी एल्गोरिदम के लिए महत्वपूर्ण है।
यहाँ सर्वर मोड पर एक लिंक है। काश, वे क्लाइंट मोड का उल्लेख नहीं करते।
यहां जीसी पर सामान्य रूप से बहुत गहन लिंक है ; यह एक अधिक मूल लेख है । निश्चित नहीं है कि या तो एड्रेस-सेवर बनाम -क्विएंट लेकिन यह प्रासंगिक सामग्री है।
नो फुल जस्ट स्टफ में, केन साइप और ग्लेन वंडेनबर्ग दोनों इस तरह की चीजों पर बहुत अच्छी बातचीत करते हैं।
मैंने 2 के बीच स्टार्टअप समय में कोई अंतर नहीं देखा है, लेकिन "-server" (सोलारिस सर्वर, हर कोई ऐप चलाने के लिए SunRays का उपयोग करके) के साथ अनुप्रयोग के प्रदर्शन में बहुत कम सुधार देखा है। वह 1.5 से कम था।
पिछली बार मैंने इस पर एक नज़र डाली थी, (और माना जाता है कि यह कुछ समय पहले था) सबसे बड़ा अंतर जो मैंने देखा था वह कचरा संग्रह में था।
IIRC:
यदि आप दो जावा वीएम, एक ग्राहक, एक सर्वर की तुलना कर सकते हैं जो कि jvisualvm टूल का उपयोग कर रहा है, तो आपको कचरा संग्रह की आवृत्ति और प्रभाव में अंतर के साथ-साथ पीढ़ियों की संख्या में भी अंतर दिखाई देना चाहिए।
मेरे पास स्क्रीनशॉट की एक जोड़ी थी जो वास्तव में अच्छी तरह से अंतर दिखाती थी, लेकिन मैं पुन: पेश नहीं कर सकता क्योंकि मेरे पास 64 बिट जेवीएम है जो केवल सर्वर वीएम को लागू करता है। (और मैं अपने सिस्टम पर 32 बिट संस्करण को डाउनलोड करने और खराब करने के लिए परेशान नहीं हो सकता।)
यह अब मामला नहीं लगता है, दोनों सर्वर और क्लाइंट VMs के साथ खिड़कियों पर कुछ कोड चलाने की कोशिश की, मुझे लगता है कि दोनों के लिए एक ही पीढ़ी के मॉडल मिल रहे हैं ...
जब 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 संस्करण में कुछ अधिक है। यह माना जाता है कि वास्तविक अंतर आपके आवेदन के व्यवहार के आधार पर रन टाइम को मापना संभव हो सकता है