जावा वीएम कितने धागे का समर्थन कर सकता है? क्या यह विक्रेता द्वारा भिन्न होता है? ऑपरेटिंग सिस्टम द्वारा? अन्य कारक?
जावा वीएम कितने धागे का समर्थन कर सकता है? क्या यह विक्रेता द्वारा भिन्न होता है? ऑपरेटिंग सिस्टम द्वारा? अन्य कारक?
जवाबों:
यह आपके द्वारा उपयोग की जा रही सीपीयू पर निर्भर करता है, ओएस पर, जो अन्य प्रक्रियाएं कर रहे हैं, उस पर जो जावा रिलीज आप उपयोग कर रहे हैं, और अन्य कारक। मैंने देखा है कि विंडोज सर्वर में मशीन को लाने से पहले 6500 थ्रेड होते हैं। अधिकांश सूत्र कुछ भी नहीं कर रहे थे, निश्चित रूप से। एक बार मशीन ने लगभग 6500 थ्रेड्स (जावा में) हिट कर दिए, पूरी मशीन को समस्या होने लगी और अस्थिर हो गई।
मेरे अनुभव से पता चलता है कि जावा (हाल के संस्करण) खुशी से कई थ्रेड्स का उपभोग कर सकते हैं क्योंकि कंप्यूटर स्वयं समस्याओं के बिना होस्ट कर सकता है।
बेशक, आपके पास पर्याप्त रैम होना चाहिए और आपको थ्रेड्स कर रहे हैं और प्रत्येक थ्रेड के लिए स्टैक करने के लिए पर्याप्त मेमोरी के साथ जावा शुरू करना होगा। आधुनिक सीपीयू (एएमडी या इंटेल की सबसे हालिया युगल पीढ़ी) और 1 - 2 गिग मेमोरी (ओएस पर निर्भर करता है) के साथ कोई भी मशीन आसानी से हजारों के साथ एक जेवीएम का समर्थन कर सकती है थ्रेड्स के ।
यदि आपको इससे अधिक विशिष्ट उत्तर की आवश्यकता है, तो आपका सबसे अच्छा शर्त प्रोफाइल बनाना है।
उम, बहुत सारे।
यहां कई पैरामीटर हैं। विशिष्ट वीएम, प्लस आमतौर पर वीएम पर रन-टाइम पैरामीटर भी होते हैं। यह ऑपरेटिंग सिस्टम द्वारा कुछ हद तक संचालित है: थ्रेड्स के लिए अंतर्निहित ओएस का क्या समर्थन है और यह उन पर क्या सीमाएं रखता है? यदि वीएम वास्तव में ओएस-स्तर के थ्रेड्स का उपयोग करता है, तो अच्छे पुराने लाल धागे / हरे धागे की चीज।
"समर्थन" का मतलब एक और सवाल है। यदि आप एक जावा प्रोग्राम लिखते हैं जो कुछ ऐसा ही है
class DieLikeADog {
public static void main(String[] argv){
for(;;){
new Thread(new SomeRunaable).start();
}
}
}
(और छोटे वाक्यविन्यास के बारे में शिकायत न करें, मैं अपने पहले कप कॉफी पर हूं) तो आपको निश्चित रूप से सैकड़ों या हजारों धागे मिलने की उम्मीद करनी चाहिए। लेकिन बना रहे हैं थ्रेड अपेक्षाकृत महंगा है, और शेड्यूलर ओवरहेड तीव्र हो सकता है; यह स्पष्ट नहीं है कि आपके पास उन धागे कुछ भी उपयोगी हो सकते हैं।
ठीक है, विरोध नहीं कर सकता। यहाँ मेरा थोड़ा परीक्षण कार्यक्रम है, एक जोड़े के साथ:
public class DieLikeADog {
private static Object s = new Object();
private static int count = 0;
public static void main(String[] argv){
for(;;){
new Thread(new Runnable(){
public void run(){
synchronized(s){
count += 1;
System.err.println("New thread #"+count);
}
for(;;){
try {
Thread.sleep(1000);
} catch (Exception e){
System.err.println(e);
}
}
}
}).start();
}
}
}
इंटेल पर ओएस / एक्स 10.5.6, और जावा 6 5 (टिप्पणियां देखें), यहां मुझे जो मिला है
नया धागा # 2547 नया धागा # 2548 नया धागा # 2549 धागा नहीं बना सकते: 5 नया धागा # 2550 धागे में अपवाद "मुख्य" java.lang.OutOfMemoryError: नया देशी धागा बनाने में असमर्थ java.lang.Thread.start0 (मूल विधि) पर java.lang.Thread.start (Thread.java and92) पर DieLikeADog.main पर (DieLikeADog.java:6)
चार्ली मार्टिन की पोस्ट को पढ़ने के बाद, मैं इस बारे में उत्सुक था कि क्या ढेर का आकार आपके द्वारा बनाए जा सकने वाले थ्रेड्स की संख्या में कोई अंतर करता है, और मैं परिणाम से पूरी तरह से बेवकूफ था।
विस्टा होम प्रीमियम SP1 पर JDK 1.6.0_11 का उपयोग करते हुए, मैंने 2 एमबी और 1024 एमबी के बीच विभिन्न ढेर आकारों के साथ चार्ली के परीक्षण एप्लिकेशन को निष्पादित किया।
उदाहरण के लिए, 2 एमबी का ढेर बनाने के लिए, मैं JVM को तर्कों -Xms2m -Xm22m के साथ आमंत्रित करूंगा।
यहाँ मेरे परिणाम हैं:
2 mb --> 5744 threads
4 mb --> 5743 threads
8 mb --> 5735 threads
12 mb --> 5724 threads
16 mb --> 5712 threads
24 mb --> 5687 threads
32 mb --> 5662 threads
48 mb --> 5610 threads
64 mb --> 5561 threads
96 mb --> 5457 threads
128 mb --> 5357 threads
192 mb --> 5190 threads
256 mb --> 5014 threads
384 mb --> 4606 threads
512 mb --> 4202 threads
768 mb --> 3388 threads
1024 mb --> 2583 threads
तो, हाँ, ढेर का आकार निश्चित रूप से मायने रखता है। लेकिन ढेर के आकार और अधिकतम थ्रेड काउंट के बीच संबंध INVERSELY आनुपातिक है।
जो अजीब है।
मुझे पता है कि यह सवाल बहुत पुराना है लेकिन मैं अपने निष्कर्षों को साझा करना चाहता हूं।
मेरा लैपटॉप प्रोग्राम को संभालने में सक्षम है जो 25,000
थ्रेड्स को जन्म देता है और उन सभी थ्रेड्स 2 सेकंड के नियमित अंतराल पर MySql डेटाबेस में कुछ डेटा लिखते हैं।
मैंने यह कार्यक्रम तब तक के 10,000 threads
लिए चलाया था , 30 minutes continuously
तब भी मेरा सिस्टम स्थिर था और मैं अन्य सामान्य ऑपरेशनों जैसे ब्राउजिंग, ओपनिंग, क्लोजिंग अदर प्रोग्राम्स आदि को करने में सक्षम था।
25,000 threads
सिस्टम के साथ slows down
लेकिन यह उत्तरदायी है।
50,000 threads
सिस्टम के साथ stopped responding
तुरन्त और मुझे अपने सिस्टम को मैन्युअल रूप से पुनरारंभ करना पड़ा।
मेरे सिस्टम विवरण इस प्रकार हैं:
Processor : Intel core 2 duo 2.13 GHz
RAM : 4GB
OS : Windows 7 Home Premium
JDK Version : 1.6
दौड़ने से पहले मैंने jvm तर्क सेट किया -Xmx2048m
।
आशा करता हूँ की ये काम करेगा।
पूर्ण सैद्धांतिक अधिकतम आम तौर पर एक प्रक्रिया के है उपयोगकर्ता पता धागा ढेर आकार से विभाजित अंतरिक्ष (हालांकि वास्तव में, यदि आपके सभी स्मृति धागा ढेर के लिए आरक्षित है, तो आप एक काम कर कार्यक्रम की ज़रूरत नहीं होगी ...)।
इसलिए 32-बिट विंडोज के तहत, उदाहरण के लिए, जहां प्रत्येक प्रक्रिया में 2GB का उपयोगकर्ता पता स्थान होता है, प्रत्येक थ्रेड को 128K स्टैक आकार देता है, आप अधिकतम 16384 थ्रेड्स (= 2 * 1024 * 1024/128) की अधिकतम अपेक्षा करेंगे। व्यवहार में, मुझे लगता है कि मैं XP के तहत लगभग 13,000 शुरू कर सकता हूं।
फिर, मुझे लगता है कि आप अनिवार्य रूप से इस बात में हैं कि क्या (ए) आप जुगलिंग का प्रबंधन कर सकते हैं कि आपके कोड में कई थ्रेड्स हैं और स्पष्ट रूप से मूर्खतापूर्ण चीजें नहीं करते हैं (जैसे कि उन सभी को एक ही वस्तु पर इंतजार करना फिर कॉल करें InformAll () ...), और (b) क्या ऑपरेटिंग सिस्टम कर सकता है। सिद्धांत रूप में, (बी) का उत्तर "हां" है यदि उत्तर (ए) भी "हां" है।
संयोग से, आप थ्रेड के कंस्ट्रक्टर में स्टैक का आकार निर्दिष्ट कर सकते हैं ; इसके लिए आपको वीएम मापदंडों के साथ गड़बड़ी (और शायद नहीं करनी चाहिए) की जरूरत नहीं है।
मुझे याद है कि एक क्लोजर की बात सुनकर उन्हें हजारों कोर (9000?) वाले ट्रेड शो में अपने एक ऐप को किसी विशेष मशीन पर चलाने के लिए मिला और इसने उन सभी को लोड कर दिया। दुर्भाग्य से, मैं अभी लिंक नहीं ढूँढ सकता (मदद?)।
उसके आधार पर, मुझे लगता है कि यह कहना सुरक्षित है कि हार्डवेयर और आपका कोड सीमित कारक हैं, जेवीएम नहीं।
चार्ली के डाइलेकियाकोड वर्ग के साथ खेलने के बाद, यह दिखता है कि जावा थ्रेड स्टैक आकार कितने धागे आप बना सकते हैं का एक बड़ा हिस्सा है।
-Xss सेट जावा थ्रेड स्टैक आकार
उदाहरण के लिए
java -Xss100k DieLikeADog
लेकिन, जावा में एक्ज़िक्यूटर इंटरफ़ेस है। मैं इसका उपयोग करूंगा, आप हजारों रन करने योग्य कार्यों को प्रस्तुत करने में सक्षम होंगे, और एक्सेक्यूटर प्रक्रिया को एक निश्चित संख्या में थ्रेड के साथ उन कार्यों को करना होगा।
Runnable
/ Callable
वास्तव में लगातार चलाने की जरूरत है, जैसे कि जब संचार को संभालना है। लेकिन यह SQL प्रश्नों के लिए एकदम सही है।
कम से कम मैक ओएस एक्स 10.6 32 बिट पर, ऑपरेटिंग सिस्टम द्वारा एक सीमा (2560) है। इस स्टैकओवरफ़्लो धागे की जाँच करें ।
आधुनिक (सिस्टमड) लिनक्स सिस्टम के लिए अतिरिक्त जानकारी।
मूल्यों के इस बारे में कई संसाधन हैं जिन्हें ट्विकिंग की आवश्यकता हो सकती है (जैसे कि जेवीएम थ्रेड्स की अधिकतम संख्या कैसे बढ़ाई जाए (लिनक्स 64 बिट ); हालाँकि, सिस्टम "टास्कमैक्स" सीमा के माध्यम से एक नई सीमा लागू की जाती है जो cgroup पर pids.max सेट करती है।
लॉगिन सत्रों के लिए उपयोगकर्ता टास्कमैक्स डिफ़ॉल्ट कर्नेल सीमा pids_max (आमतौर पर 12,288) का 33% है और इसे /etc/systemd/logind.conf में ओवरराइड किया जा सकता है।
सेवाओं के लिए DefaultTasksMax डिफ़ॉल्ट कर्नेल सीमा pids_max (आमतौर पर 4,915) का 15% है। आप "Systemctl एडिट" में टास्कमैक्स सेट करके सेवा के लिए इसे ओवरराइड कर सकते हैं या DefaultTasksMax को /etc/systemd/system.conf में अपडेट कर सकते हैं
आप किसी भी थ्रेड को संसाधित कर सकते हैं; कोई सीमा नही है। मैंने मूवी देखते समय और नेटबीन्स का उपयोग करते हुए निम्नलिखित कोड चलाया, और इसने मशीन को बिना रुके / ठीक से काम किया। मुझे लगता है कि आप इस कार्यक्रम की तुलना में और भी अधिक धागे रख सकते हैं।
class A extends Thread {
public void run() {
System.out.println("**************started***************");
for(double i = 0.0; i < 500000000000000000.0; i++) {
System.gc();
System.out.println(Thread.currentThread().getName());
}
System.out.println("************************finished********************************");
}
}
public class Manager {
public static void main(String[] args) {
for(double j = 0.0; j < 50000000000.0; j++) {
A a = new A();
a.start();
}
}
}
main
फेंक देगा OutOfMemoryError
, यह कहते हुए कि यह कोई और धागा नहीं बना सकता है। शायद @AnilPal, आपने ध्यान नहीं दिया। मैं main(..)
विधि में एक और प्रिंट स्टेटमेंट सहित सुझाव देता हूं , यह स्पष्ट रूप से देखने के लिए कि त्रुटि को फेंकने के बाद नए थ्रेड्स बनाना कब बंद हो जाता है।