जहाँ तक मुझे पता है, MappedByteBuffer के कई लाभ हैं, जैसे:

  1. यह यूजर स्पेस मेमोरी एड्रेस को कर्नेल स्पेस मेमोरी एड्रेस में मैप करता है, ताकि फाइल से पढ़ते समय यह मेमोरी कॉपी को कर्नेल स्पेस से यूजर स्पेस में जाने से बचाए

  2. फ़ाइल में एक टुकड़े के पहले पढ़ने के बाद (आदि बफर में 0 से 100 तक ऑफसेट), यह टुकड़ा मेमोरी में कैश किया जाएगा, इसलिए जब दूसरी बार आप बफर से उसी टुकड़े को पढ़ते हैं, तो आप इसे पढ़ रहे हैं सीधे मेमोरी से लेकिन डिस्क से नहीं।

मेरा सवाल यह है कि:

  1. क्या ऊपर मेरी समझ सही है?

  2. अगर मेरी समझ सही है, जब आप केवल एक बार टुकड़ा पढ़ते हैं (इसे फिर कभी नहीं पढ़ते हैं तो यह इसे स्मृति से नहीं पढ़ेगा), क्या यह FileChannel.read(buffer, position) का उपयोग करके और MappedByteBuffer.get(byte) का उपयोग करके समान है [], ऑफसेट, लंबाई)?

  3. किसी फ़ाइल में रैंडम एक्सेस करने के लिए (एक ही टुकड़े को बार-बार नहीं पढ़ना), क्या FileChannel अधिक कुशल होगा क्योंकि MappedByteBuffer मेमोरी को मैप करेगा जबकि FileChannel को मेमोरी की आवश्यकता नहीं है?

  4. मैप्डबाइटबफर का उपयोग करने के बीच क्या अंतर है और मैं पूरी फाइल को अपनी मेमोरी में लोड करता हूं। MappedByteBuffer का लाभ यह है कि यह JVM हीप के बाहर एक मेमोरी का उपयोग करता है, इसलिए कोई GC चिंता नहीं है?

1
Alexis 24 अप्रैल 2018, 10:53

1 उत्तर

सबसे बढ़िया उत्तर

आइए मैं आपको एक-एक करके सवालों के जवाब देता हूं।

जहाँ तक मुझे पता है, MappedByteBuffer के कई लाभ हैं, जैसे:

  1. यह यूजर स्पेस मेमोरी एड्रेस को कर्नेल स्पेस मेमोरी एड्रेस में मैप करता है, ताकि यह फाइल से पढ़ते समय मेमोरी कॉपी को कर्नेल स्पेस से यूजर स्पेस में जाने से बचा सके

  2. फ़ाइल में एक टुकड़े के पहले पढ़ने के बाद (आदि बफर में 0 से 100 तक की ऑफसेट), इस टुकड़े को मेमोरी में कैश किया जाएगा, इसलिए जब आप दूसरी बार बफर से उसी टुकड़े को पढ़ते हैं, तो आप इसे सीधे मेमोरी से पढ़ रहे हैं लेकिन डिस्क से नहीं।

आपके कथन अमान्य नहीं हैं। हालांकि, यह महत्वपूर्ण है कि साधारण तथ्य को याद न करें। फ़ाइल डेटा तक पहुंच में हमेशा कैश शामिल होता है (सिवाय इसके कि जब यह न हो)। मेमोरी मैपिंग के मामले में कैश से पेजों को आपके एड्रेस स्पेस में मैप किया जाता है, जिसमें FileChannel अतिरिक्त मेमोरी कॉपी शामिल होती है।

अगर मेरी समझ सही है, जब आप केवल एक बार टुकड़ा पढ़ते हैं (इसे फिर कभी नहीं पढ़ते हैं तो यह इसे स्मृति से नहीं पढ़ेगा), क्या यह FileChannel.read(buffer, position) का उपयोग करके और MappedByteBuffer.get(byte) का उपयोग करके समान है [], ऑफसेट, लंबाई)?

नहीं, FileChannel.read(buffer, position) में अतिरिक्त मेमोरी कॉपी शामिल है। डेटा वैसे भी कुछ समय के लिए कैश में हैंग होने वाला है।

किसी फ़ाइल में रैंडम एक्सेस करने के लिए (एक ही टुकड़े को बार-बार नहीं पढ़ना), क्या FileChannel अधिक कुशल होगा क्योंकि MappedByteBuffer मेमोरी को मैप करेगा जबकि FileChannel को मेमोरी की आवश्यकता नहीं है?

आपका तर्क गलत है। डेटा एक्सेस पैटर्न के साथ, FileChannel मेमोरी कॉपी के लिए अतिरिक्त मेमोरी करता है, MappedByteBuffer नहीं करता है। इसके अलावा, मेमोरी मैपिंग अनिवार्य रूप से आलसी है। डेटा केवल डिस्क से लोड किया जाता है जब आप संबंधित मेमोरी पेज तक पहुंच रहे होते हैं।

मैप्डबाइटबफर का उपयोग करने के बीच क्या अंतर है और मैं पूरी फाइल को अपनी मेमोरी में लोड करता हूं। MappedByteBuffer का लाभ यह है कि यह JVM हीप के बाहर एक मेमोरी का उपयोग करता है, इसलिए कोई GC चिंता नहीं है?

आप अपने बॉक्स पर भौतिक मेमोरी से बड़े परिमाण के फ़ाइल ऑर्डर को मैप कर सकते हैं (एकल मैप्डबाइटबफ़र 2GiB तक सीमित है, इसलिए कई मैपिंग की आवश्यकता होगी)। फ़ाइल डेटा एक्सेस का एक पृष्ठ, हालांकि मैपिंग को ओएस द्वारा किसी भी समय वापस लिया जा सकता है। जहां तक ​​GC का संबंध है, वास्तव में, MappedByteBuffer ढेर पर कब्जा नहीं करता है।

FileChannel और MappedByteBuffer के बीच क्या चुनना है?

मेमोरी मैप किए गए डेटा का उपयोग करने से अन्य बुरा प्रभाव पड़ता है।

  1. मेमोरी में डेटा तक कोई भी एक्सेस IO ऑपरेशन बन सकता है (यदि मेमोरी पेज कैश्ड नहीं है)। अर्थात। प्रत्येक ByteBuffer.get() कॉल संभावित रूप से अवरुद्ध हो रही है।
  2. MappedByteBuffer का निपटारा नहीं किया जा सकता है। मेमोरी मैपिंग GC द्वारा साफ किए जाने तक सक्रिय रहेगी।

यह MappedByteBuffer को डेटा तक पहुंचने के लिए एक आकर्षक और शायद ही कभी इस्तेमाल किया जाने वाला तरीका बनाता है।

अगर आपको से बचने की सलाह दी जाती है तो MappedByteBuffer if

  1. आपका आवेदन इंटरैक्टिव है और प्रतिक्रिया समय महत्वपूर्ण है।
  2. आप डेटा को संसाधित करने के लिए सक्रिय रूप से एकाधिक थ्रेड्स का उपयोग कर रहे हैं (आईओ पर अटका हुआ एकल थ्रेड अन्य थ्रेड्स द्वारा कैस्केडिंग अवरोधन का कारण हो सकता है)।
  3. आप गैर-अवरुद्ध फ़ाइल IO चाहते हैं
3
Community 20 जून 2020, 12:12