2013-08-04 7 views
7

मैं कई बार स्ट्रीम का उपयोग कर रहा हूं लेकिन मैंने कभी भी इस बारे में बहुत कुछ नहीं पढ़ा कि वे वास्तव में कैसे काम करते हैं। न ही मैं उनके बारे में बहुत कुछ जानता हूं कि एक धारा सिर्फ एक रूपक है। एक धारा केवल बाइट्स के अनुक्रम का प्रतिनिधित्व करती है। मैं वास्तव में काम करने के बारे में बहुत कुछ नहीं जानता, मुझे लगता है कि जावा में एक फ़ाइल स्ट्रीम खोलने से ओएस के साथ बातचीत होती है जिसमें स्ट्रीम में "पॉइंटर" देने की कार्यक्षमता होती है।जावा में स्ट्रीम मेमोरी खपत को कैसे प्रभावित करती है?

मूल रूप से मेरा प्रश्न यह है कि स्ट्रीम मेमोरी खपत को कैसे प्रभावित करती है। जब आपके पास उदाहरण के लिए एक इनपुट स्ट्रीम है और आप इसे पढ़ना शुरू करते हैं तो आप केवल बाइट्स की मात्रा के साथ मेमोरी खपत में वृद्धि करना शुरू कर देते हैं? जावा में स्ट्रीम खोलते समय आप वास्तव में पढ़ने से पहले पूर्ण फ़ाइल लोड नहीं करते हैं? यदि आप एक स्ट्रीम से पढ़ते हैं और सीधे किसी अन्य स्ट्रीम पर लिखते हैं तो आप केवल उस बाइट्स की मात्रा के साथ स्मृति को बढ़ाते हैं (और संभावित रूप से बफर में)? यदि आप जावा में बाइट सरणी में बाइट्स पढ़ते हैं तो आप स्मृति के खपत को फ़ाइल के आकार के साथ बढ़ाते हैं?

एक अजीब प्रश्न की तरह लग सकता है लेकिन मुझे मेरी समझ पर कुछ मार्गदर्शन/सुधार की आवश्यकता हो सकती है। धन्यवाद।

+0

आपके पास एक बहुत अच्छी व्याख्या है [यहां] (http://www.ibm.com/developerworks/library/j-zerocopy/index.html) शून्य प्रति। यह बफर और स्मृति उपयोग को भी समझाता है। –

उत्तर

3

से पढ़ने शुरू करने के बाद लगभग कोई मेमोरी ओवरहेड नहीं है। नई ऑब्जेक्ट आवंटन के लिए JVM में फ़ाइल खोलने के लिए बहुत छोटा ओएस-ओवरहेड और एक छोटा ओवरहेड है। यदि आप BufferedInputStream का उपयोग करते हैं तो डिफ़ॉल्ट रूप से 8KB का उपयोग करने पर भी एक छोटा ओवरहेड हो सकता है।

लेखन के लिए ओवरहेड बहुत अधिक पर निर्भर करता है कि आप कहां लिखते हैं। यदि यह FileOutputStream है, तो यह ऊपर वर्णित जैसा ही है। यदि यह ByteArrayOutputStream है, तो सबसे खराब स्थिति में (3 * स्ट्रीम लम्बाई) बाइट में यह (2 * स्ट्रीम लम्बाई) बाइट्स है और है। अर्थात। एक InputStream से बाइट सरणी 30k बाइट्स में 10k बाइट कॉपी करने के लिए सबसे खराब मामले में आवंटित किया जाएगा।

इसका कारण यह है कि ByteArrayOutputStream आकार की वृद्धि के बाद 2 गुना वृद्धि हुई है और जब आप toByteArray() पर कॉल करते हैं तो यह एक नया बफर भी आवंटित करता है।

5

उपरोक्त सभी उत्तरों के बहुत अच्छे उत्तर हैं, लेकिन मुझे विश्वास नहीं है कि वे स्मृति खपत के बारे में आपके मूल प्रश्न का उत्तर देते हैं।

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

धारा के तीसरे प्रकार एक स्मृति धारा (यानी ByteArrayInput/ouput) इन के रूप में अधिक स्मृति का उपयोग के रूप में आप उन्हें लिख सकते हैं और जरूरत के रूप में विकसित और नहीं उनकी स्मृति के निपटान जब तक संदर्भ गिनती शून्य करने के लिए चला जाता है जाएगा (वे कर रहे हैं है अब इस्तेमाल नहीं किया जाता)। ये धाराएं बहुत उपयोगी हैं लेकिन स्पष्ट रूप से बहुत सारी स्मृति का उपभोग कर सकती हैं।

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

संबंधित मुद्दे