जावा वीएम कितने धागे का समर्थन कर सकता है?


212

जावा वीएम कितने धागे का समर्थन कर सकता है? क्या यह विक्रेता द्वारा भिन्न होता है? ऑपरेटिंग सिस्टम द्वारा? अन्य कारक?

जवाबों:


170

यह आपके द्वारा उपयोग की जा रही सीपीयू पर निर्भर करता है, ओएस पर, जो अन्य प्रक्रियाएं कर रहे हैं, उस पर जो जावा रिलीज आप उपयोग कर रहे हैं, और अन्य कारक। मैंने देखा है कि विंडोज सर्वर में मशीन को लाने से पहले 6500 थ्रेड होते हैं। अधिकांश सूत्र कुछ भी नहीं कर रहे थे, निश्चित रूप से। एक बार मशीन ने लगभग 6500 थ्रेड्स (जावा में) हिट कर दिए, पूरी मशीन को समस्या होने लगी और अस्थिर हो गई।

मेरे अनुभव से पता चलता है कि जावा (हाल के संस्करण) खुशी से कई थ्रेड्स का उपभोग कर सकते हैं क्योंकि कंप्यूटर स्वयं समस्याओं के बिना होस्ट कर सकता है।

बेशक, आपके पास पर्याप्त रैम होना चाहिए और आपको थ्रेड्स कर रहे हैं और प्रत्येक थ्रेड के लिए स्टैक करने के लिए पर्याप्त मेमोरी के साथ जावा शुरू करना होगा। आधुनिक सीपीयू (एएमडी या इंटेल की सबसे हालिया युगल पीढ़ी) और 1 - 2 गिग मेमोरी (ओएस पर निर्भर करता है) के साथ कोई भी मशीन आसानी से हजारों के साथ एक जेवीएम का समर्थन कर सकती है थ्रेड्स के ।

यदि आपको इससे अधिक विशिष्ट उत्तर की आवश्यकता है, तो आपका सबसे अच्छा शर्त प्रोफाइल बनाना है।


86

उम, बहुत सारे।

यहां कई पैरामीटर हैं। विशिष्ट वीएम, प्लस आमतौर पर वीएम पर रन-टाइम पैरामीटर भी होते हैं। यह ऑपरेटिंग सिस्टम द्वारा कुछ हद तक संचालित है: थ्रेड्स के लिए अंतर्निहित ओएस का क्या समर्थन है और यह उन पर क्या सीमाएं रखता है? यदि वीएम वास्तव में ओएस-स्तर के थ्रेड्स का उपयोग करता है, तो अच्छे पुराने लाल धागे / हरे धागे की चीज।

"समर्थन" का मतलब एक और सवाल है। यदि आप एक जावा प्रोग्राम लिखते हैं जो कुछ ऐसा ही है

   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)

10
जेवीएम की शुरुआत आपने कितनी मेमोरी के साथ की थी? वह मायने रखता है।
एडी

10
जावा 6 अपडेट 13, उबंटू 8.10 32 बिट, 4 जी रैम, डिफॉल्ट जेवीएम सेटिंग्स = 6318 थ्रेड्स।
स्टीव के

9
हे, थ्रेड स्टैक आकार के साथ खेलते हैं। java -Xss100k ने मुझे लिनक्स में 19702 धागे बनाने की अनुमति दी।
स्टीव के

21
java -Xss50k ने मुझे लगभग 32k धागे दिए। हालांकि मेरे 4 जी के राम को अधिकतम कर दिया। मुझे जावा को मारने के लिए एक नई प्रक्रिया को कांटा करने के लिए अपनी मशीन पर पर्याप्त मेमोरी वापस पाने के लिए कुछ चलने वाली प्रक्रियाओं को रोकना पड़ा;) - अच्छा समय।
स्टीव के

21
विंडोज़ 7 पर जावा 7 का उपयोग करते हुए मैंने अपने सिस्टम के मरने से पहले सिर्फ 200,000 धागे बनाए। कार्य प्रबंधक ने 8GB RAM का उपयोग करके प्रक्रिया को दिखाया। निश्चित नहीं कि यह वहाँ क्यों रुका, हालाँकि ... मेरे कंप्यूटर पर 12GB RAM है। तो यह किसी अन्य सीमा से टकराना हो सकता है।
डोबेस वांडरमेर

50

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

विस्टा होम प्रीमियम 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 आनुपातिक है।

जो अजीब है।


11
अगर कोई धागा उस आकार का ढेर दिया जाता है तो समझ में आएगा।
थोरबजोरन राव एंडरसन

1
कैविएट: मेरी मशीन में 2583 जीबी रैम नहीं है। या अदला-बदली करें। और JVM थ्रेड-लोकल हीप स्पेस आवंटित नहीं करता है। तो यह नहीं हो सकता है ...
benjismith

49
ढेर का आकार ढेर के लिए उपलब्ध पते की जगह को कम करता है। 256K / stack का पता स्थान समझ में आता है।
टॉम हैटिन

1
ऐ, यह वही बात दिखाता
Toby

39

मुझे पता है कि यह सवाल बहुत पुराना है लेकिन मैं अपने निष्कर्षों को साझा करना चाहता हूं।

मेरा लैपटॉप प्रोग्राम को संभालने में सक्षम है जो 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

आशा करता हूँ की ये काम करेगा।


2
"धीमा हो जाता है" गमागमन की तरह ध्वनि।
थोरबजोरन रावन एंडरसन 15

धन्यवाद। यह बहुत ठोस मशीन थी और लगभग 8 वर्षों तक ठीक काम किया जब तक कि अचानक इसे बूट करना बंद नहीं कर दिया। मैंने बस विंडोज के बजाय उस पर उबंटू स्थापित किया और इसने फिर से संख्याओं को कम करना शुरू कर दिया :)
शेखर

Ubuntu मसाला के साथ फ्राइड कोर 2 जोड़ी: D
पासुपथी राजमनिकम

31

पूर्ण सैद्धांतिक अधिकतम आम तौर पर एक प्रक्रिया के है उपयोगकर्ता पता धागा ढेर आकार से विभाजित अंतरिक्ष (हालांकि वास्तव में, यदि आपके सभी स्मृति धागा ढेर के लिए आरक्षित है, तो आप एक काम कर कार्यक्रम की ज़रूरत नहीं होगी ...)।

इसलिए 32-बिट विंडोज के तहत, उदाहरण के लिए, जहां प्रत्येक प्रक्रिया में 2GB का उपयोगकर्ता पता स्थान होता है, प्रत्येक थ्रेड को 128K स्टैक आकार देता है, आप अधिकतम 16384 थ्रेड्स (= 2 * 1024 * 1024/128) की अधिकतम अपेक्षा करेंगे। व्यवहार में, मुझे लगता है कि मैं XP के तहत लगभग 13,000 शुरू कर सकता हूं।

फिर, मुझे लगता है कि आप अनिवार्य रूप से इस बात में हैं कि क्या (ए) आप जुगलिंग का प्रबंधन कर सकते हैं कि आपके कोड में कई थ्रेड्स हैं और स्पष्ट रूप से मूर्खतापूर्ण चीजें नहीं करते हैं (जैसे कि उन सभी को एक ही वस्तु पर इंतजार करना फिर कॉल करें InformAll () ...), और (b) क्या ऑपरेटिंग सिस्टम कर सकता है। सिद्धांत रूप में, (बी) का उत्तर "हां" है यदि उत्तर (ए) भी "हां" है।

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


1
इसलिए 64-बिट OS का उपयोग करें। हम सभी अब तक 64-बिट प्रोसेसर का उपयोग कितने समय से कर रहे हैं?
टॉम हॉल्टिन -

ज़रूर, मैं सिर्फ एक सैद्धांतिक बनाम व्यावहारिक सीमा का उदाहरण दे रहा हूं। ध्यान रहे, वहाँ 32-बिट मशीनों (सर्वर सहित) की एक बहुत बड़ी संख्या अभी भी है ...
नील कॉफ़ी

2

मुझे याद है कि एक क्लोजर की बात सुनकर उन्हें हजारों कोर (9000?) वाले ट्रेड शो में अपने एक ऐप को किसी विशेष मशीन पर चलाने के लिए मिला और इसने उन सभी को लोड कर दिया। दुर्भाग्य से, मैं अभी लिंक नहीं ढूँढ सकता (मदद?)।

उसके आधार पर, मुझे लगता है कि यह कहना सुरक्षित है कि हार्डवेयर और आपका कोड सीमित कारक हैं, जेवीएम नहीं।


क्या आप फिर से देख सकते हैं? मैं इसे देखना चाहता हूं - यह दिलचस्प लगता है और समर्थन करता है कि कार्यात्मक भाषाएं कोर के पार बड़े पैमाने पर आसान हैं।
थोरबजोरन रावन एंडरसन

क्या आप उससे लिंक प्रदान कर सकते हैं? मुझे पता है कि क्लिफ क्लिक, जूनियर, अज़ुल सिस्टम के लीड इंजीनियर ने अज़ुल की सबसे बड़ी जेसीए प्रणाली (अज़ुल वेगा 3 सीरीज 7300 मॉडल 7380D: AzulSystems.Com/products/compute_appliance_specs.htm ) पर 864 कोर और 768 के साथ रिच हिकी की एंट कॉलोनी सिमुलेशन चलाया। जीबी रैम, और 700 चींटियों ने 700 कोर को अधिकतम करने में कामयाब रहे। लेकिन 9000 कोर, यह बहुत प्रभावशाली है। मशीन किस तरह की थी?
जोर्ग डब्ल्यू मित्तग

यह "चींटियों" का अनुकरण था जो मैं मानता हूं - यहां एक लिंक है जहां रिच हिकी ( क्लोजर निर्माता) इस बारे में बात करता है - blip.tv/clojure/clojure-concurrency-819147 । यह 800+ कोर के साथ कुछ बड़े अज़ुल सिस्टम बॉक्स पर था, मुख्य रूप से यह प्रदर्शित करने के लिए किया गया था कि मल्टी-कोर कंसर्टिबिलिटी को संभालने के लिए क्लोजर कितना अच्छा है।
मिकेरा

@mikera lins की समय सीमा समाप्त हो गई है।
Thorbjørn रावन एंडरसन

2

चार्ली के डाइलेकियाकोड वर्ग के साथ खेलने के बाद, यह दिखता है कि जावा थ्रेड स्टैक आकार कितने धागे आप बना सकते हैं का एक बड़ा हिस्सा है।

-Xss सेट जावा थ्रेड स्टैक आकार

उदाहरण के लिए

java -Xss100k DieLikeADog

लेकिन, जावा में एक्ज़िक्यूटर इंटरफ़ेस है। मैं इसका उपयोग करूंगा, आप हजारों रन करने योग्य कार्यों को प्रस्तुत करने में सक्षम होंगे, और एक्सेक्यूटर प्रक्रिया को एक निश्चित संख्या में थ्रेड के साथ उन कार्यों को करना होगा।


13
क्या हम इसे DieLikeACat नाम दे सकते हैं? जब तक आप इसे नहीं चलाते तब तक यह न तो मरा होगा और न ही जीवित होगा।
गुडविन

एक्जिक्यूटर्स पर इशारा करने के लिए धन्यवाद, लोगों को इसका अधिक बार उपयोग करना चाहिए। लेकिन यह काम नहीं करेगा अगर Runnable/ Callableवास्तव में लगातार चलाने की जरूरत है, जैसे कि जब संचार को संभालना है। लेकिन यह SQL प्रश्नों के लिए एकदम सही है।
मैथ्यू


0

थ्रेड्स की अधिकतम संख्या निम्नलिखित बातों पर निर्भर करती है:

  • माइक्रोप्रोसेसर, रैम जैसे हार्डवेयर कॉन्फ़िगरेशन।
  • ऑपरेटिंग सिस्टम जैसे कि यह 32-बिट या 64-बिट है
  • रन विधि के अंदर कोड। यदि रन विधि के अंदर कोड विशाल है तो सिंगल थ्रेड ऑब्जेक्ट के लिए अधिक मेमोरी की आवश्यकता होगी

  • 0

    आधुनिक (सिस्टमड) लिनक्स सिस्टम के लिए अतिरिक्त जानकारी।

    मूल्यों के इस बारे में कई संसाधन हैं जिन्हें ट्विकिंग की आवश्यकता हो सकती है (जैसे कि जेवीएम थ्रेड्स की अधिकतम संख्या कैसे बढ़ाई जाए (लिनक्स 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 में अपडेट कर सकते हैं


    0

    वर्ष 2017 ... DieLikeADog वर्ग।

    नया धागा # 92459 धागे में अपवाद "मुख्य" java.lang.OutOfMemoryError: नया देशी धागा बनाने में असमर्थ

    i7-7700 16gb ram


    ऑफकोर्स उत्तर अलग-अलग होंगे। मुझे 6 जीबी रैम के साथ 10278 मिला है।
    जेमी

    -4

    आप किसी भी थ्रेड को संसाधित कर सकते हैं; कोई सीमा नही है। मैंने मूवी देखते समय और नेटबीन्स का उपयोग करते हुए निम्नलिखित कोड चलाया, और इसने मशीन को बिना रुके / ठीक से काम किया। मुझे लगता है कि आप इस कार्यक्रम की तुलना में और भी अधिक धागे रख सकते हैं।

    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();
            }
        }
    }

    7
    मुझे पता है कि यह टिप्पणी बहुत देर से है, लेकिन मेरा मानना ​​है कि जिस कारण से आप इन कई थ्रेडों को शुरू करने और चलाने में सक्षम थे, क्योंकि (सामान्य और उचित सिस्टम कॉन्फ़िगरेशन को मानते हुए) प्रत्येक थ्रेड मूल रूप से आउटपुट के बाहर एक लाइन प्रिंट करता है और उसके बाद और कोई कारण नहीं है मौजूद है और जल्द ही मार दिया जाता है, जिससे संसाधनों की निरंतर उपलब्धता सुनिश्चित होती है।
    ucsunil

    @ucsunil यह सच नहीं है। मुझे लगता है कि आपने कोड को गलत बताया है। मैंने अभी इसकी कोशिश की और अलग-अलग धागे न केवल पहली पंक्ति को प्रिंट कर रहे हैं, बल्कि उनके नाम भी हैं। जिसका अर्थ है कि वे सक्रिय हैं। अगर आपको लगता है कि कचरा संग्रह अप्रतिबंधित थ्रेड को रीसायकल करेगा, तो यह यहाँ नहीं है
    इवगेनी सर्गेव

    1
    हालाँकि, थोड़ी देर के बाद, मेरी मशीन पर mainफेंक देगा OutOfMemoryError, यह कहते हुए कि यह कोई और धागा नहीं बना सकता है। शायद @AnilPal, आपने ध्यान नहीं दिया। मैं main(..)विधि में एक और प्रिंट स्टेटमेंट सहित सुझाव देता हूं , यह स्पष्ट रूप से देखने के लिए कि त्रुटि को फेंकने के बाद नए थ्रेड्स बनाना कब बंद हो जाता है।
    इवगेनी सर्गेव

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