दिलचस्प पोस्ट
एक डाटाबेस में ब्लॉप्स के रूप में दस्तावेज़ संग्रह करना – कोई नुकसान? हम FtpWebRequest के साथ अपलोड करने के लिए प्रगति बार कैसे दिखा सकते हैं ओएस कैसे प्राप्त करें जिस पर PHP चल रहा है? HTML तालिका के लिए JSON वस्तुओं को पार्स करना मूल फ़ोल्डर से मॉड्यूल आयात करना PHP v4 UUID उत्पन्न करने के लिए फ़ंक्शन क्यों dict.get (कुंजी) बजाय dict के? डेटा को 3 सेटों (ट्रेन, सत्यापन और परीक्षण) में कैसे विभाजित किया जाए? मुख्य कार्य में "WINAPI" क्या होता है? एचटीएमएल 5 कैनवास सीटीएक्स। फेल टेक्स्ट लाइन ब्रेक्स नहीं करेंगे? सादा पाठ के रूप में HTML टैग कैसे प्रदर्शित करें C ++ कोड में कौन सी सीआई / ओ लाइब्रेरी का उपयोग किया जाना चाहिए? जावा में थ्रेड को ठीक से कैसे रोकें? क्या जावास्क्रिप्ट / jQuery में HTML तत्व ऑब्जेक्ट क्लोन करना संभव है? Asp.net पहचान पासवर्ड हैशिंग

ByteBuffer.allocate () बनाम ByteBuffer.allocateDirect ()

allocate() या allocateDirect() करने के allocateDirect() , यह सवाल है

कुछ सालों के लिए मैं बस सोचा था कि DirectByteBuffer एस ओएस स्तर पर एक सीधी मेमोरी मैपिंग है, क्योंकि यह HeapByteBuffer एस की तुलना में कॉल प्राप्त करने के साथ तेज़ी से प्रदर्शन करेगा। मैं अब तक वास्तव में स्थिति के बारे में सटीक विवरण जानने में कभी दिलचस्पी नहीं करता था। मैं जानना चाहता हूं कि किस प्रकार के दो प्रकार के ByteBuffer एस तेजी से और किन स्थितियों पर हैं

वेब के समाधान से एकत्रित समाधान "ByteBuffer.allocate () बनाम ByteBuffer.allocateDirect ()"

अपने उत्कृष्ट पुस्तक जावा एनआईओ में रॉन हिट्स को लगता है कि मैंने जो सोचा था वह आपके प्रश्न का एक अच्छा जवाब हो सकता है:

ऑपरेटिंग सिस्टम मेमोरी क्षेत्रों में आई / ओ ऑपरेशन करते हैं I जहां तक ​​ऑपरेटिंग सिस्टम का संबंध है, ये स्मृति क्षेत्रों, बाइट्स के निकटतम दृश्य हैं। यह कोई आश्चर्य नहीं है कि केवल बाइट बफ़र्स I / O संचालन में भाग लेने के लिए योग्य हैं। यह भी याद रखें कि ऑपरेटिंग सिस्टम सीधे प्रक्रिया के पते स्थान तक पहुंच जाएगा, इस मामले में जेवीएम प्रक्रिया, डेटा को स्थानांतरित करने के लिए। इसका अर्थ है कि स्मृति क्षेत्रों जो I / O peration के लक्ष्य हैं, बाइट्स के निकटतम दृश्य होना चाहिए। जेवीएम में, बाइट्स की एक सरणी को स्मृति में संचित रूप से संग्रहित नहीं किया जा सकता है, या कचरा कलेक्टर इसे किसी भी समय स्थानांतरित कर सकता है। एरेजे जावा में ऑब्जेक्ट हैं, और जिस तरह से डेटा उस ऑब्जेक्ट में संग्रहीत होता है, वह एक जेवीएम कार्यान्वयन से भिन्न हो सकता है

इस कारण से, प्रत्यक्ष बफर की धारणा पेश की गई थी डायरेक्ट बफ़र्स चैनल और देशी I / O रूटीन के साथ बातचीत के लिए लक्षित हैं। वे मेमोरी क्षेत्र में बाइट तत्वों को संग्रहीत करने का सर्वोत्तम प्रयास करते हैं, जो एक चैनल प्रत्यक्ष, या कच्चा उपयोग के लिए, देशी कोड का इस्तेमाल करके ऑपरेटिंग सिस्टम को बता सकता है कि स्मृति क्षेत्र को सीधा तरीके से निकालना या भरना है।

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

  1. एक अस्थायी प्रत्यक्ष बाइटबफर ऑब्जेक्ट बनाएं
  2. Nondirect बफर की सामग्री को अस्थायी बफर में कॉपी करें
  3. अस्थायी बफ़र का उपयोग करके निम्न-स्तर I / O ऑपरेशन करें।
  4. अस्थायी बफर ऑब्जेक्ट गुंजाइश से बाहर हो जाता है और अंततः कूड़ा एकत्र किया जाता है।

यह संभावित रूप से प्रत्येक आई / ओ पर बफर प्रतिलिपि और ऑब्जेक्ट मंथन का परिणाम हो सकता है, जो वास्तव में उन चीजों की तरह हैं जिन्हें हम बचाना चाहते हैं हालांकि, कार्यान्वयन के आधार पर, चीजें यह खराब नहीं हो सकतीं। रनटाइम संभवतः कैश करेगा और सीधे बफ़र्स का पुन: उपयोग करेगी या थ्रूपुट को बढ़ावा देने के लिए अन्य चालाक चालें करेगी। यदि आप बस एक बार उपयोग के लिए बफर बना रहे हैं, तो अंतर महत्वपूर्ण नहीं है दूसरी ओर, यदि आप बार-बार उच्च-प्रदर्शन वाले परिदृश्य में बफर का उपयोग कर रहे हैं, तो आप सीधे बफ़र्स को आवंटित करने और उनका पुन: उपयोग करने से बेहतर हैं।

डायरेक्ट बफ़र्स I / O के लिए इष्ट हैं, लेकिन nondirect बाइट बफ़र्स की तुलना में वे अधिक महंगा हो सकते हैं। सीधे बफ़र्स द्वारा उपयोग की जाने वाली स्मृति को मानक, ऑपरेटिंग सिस्टम-विशिष्ट कोड के माध्यम से कॉल करके आवंटित किया जाता है, जो मानक जेवीएम हीप को दरकिनार करते हैं। मेजबान ऑपरेटिंग सिस्टम और जेवीएम कार्यान्वयन के आधार पर, सीधे बफ़र्स को सेट करना और फाड़ना ढेर-निवासी बफ़र्स की तुलना में काफी अधिक महंगा हो सकता है सीधे बफ़र्स के मेमोरी-स्टोरेज एरिया कचरा संग्रहण के अधीन नहीं हैं क्योंकि वे मानक जेवीएम हीप के बाहर हैं।

प्रत्यक्ष बनाम नॉनडॉइड बफ़र्स का उपयोग करने के प्रदर्शन के कारण व्यापक रूप से JVM, ऑपरेटिंग सिस्टम और कोड डिज़ाइन के आधार पर भिन्न हो सकते हैं। ढेर के बाहर मेमोरी आवंटित करके, आप अपने आवेदन को अतिरिक्त बलों के अधीन कर सकते हैं जिनमें से JVM अनजान है जब अतिरिक्त चलती हिस्सों को खेलने में लाते हैं, तो सुनिश्चित करें कि आप इच्छित प्रभाव को प्राप्त कर रहे हैं। मैं पुरानी सॉफ्टवेयर की सिफारिश करता हूं: पहले यह काम करें, फिर इसे तेज़ी से बनाएं ऑप्टिमाइजेशन अप मोर्चे के बारे में ज्यादा चिंता न करें; सही पर पहले ध्यान केंद्रित करें JVM कार्यान्वयन बफर कैशिंग या अन्य ऑप्टिमाइज़ेशन करने में सक्षम हो सकता है जो आपको आपके भाग पर बहुत अधिक अनावश्यक प्रयास किए बिना प्रदर्शन की आवश्यकता देगा।

Jvm के अंदर पहुंच के लिए सीधे बफ़र्स को तेजी से आने की उम्मीद नहीं है। उनका फायदा तब आता है जब आप उन्हें मूल कोड में भेजते हैं – जैसे, सभी प्रकार के चैनलों के पीछे कोड।

अपने खुद के माप करने के लिए सर्वश्रेष्ठ त्वरित उत्तर यह है कि एक allocateDirect() बफर से भेजने से आकार के आधार पर allocate() संस्करण (फाइल / कॉपी / नल में प्रतिलिपि के रूप में परीक्षण किया गया allocate() तुलना में 25% से 75% कम समय लगता है, लेकिन यह कि आवंटन ही काफी धीमी हो (100x का एक पहलू भी)

सूत्रों का कहना है:

  • क्यों ByteBuffer.allocate () और ByteBuffer.allocateDirect () के बीच अजीब प्रदर्शन वक्र अंतर

  • ByteBuffer.allocateDirect हास्यास्पद धीमी गति से

  • ऐरे, बफर या डायरेक्ट बफर का उपयोग कब किया जाए

क्योंकि डायरेक्टबिटबफर ओएस स्तर पर एक सीधी मेमोरी मैपिंग हैं

वे नहीं हैं ये सिर्फ सामान्य आवेदन प्रक्रिया मेमोरी हैं, लेकिन जावा जीसी के दौरान स्थानांतरण के अधीन नहीं है जो जेएनआई परत के अंदर चीजों को सरल बनाता है। आप जो वर्णन करते हैं वह MappedByteBuffer पर लागू होता है

कि यह प्राप्त / डाल कॉल के साथ जल्दी प्रदर्शन करेंगे

निष्कर्ष premiss से पालन नहीं करता है; प्रेसीज गलत है; और निष्कर्ष भी गलत है। एक बार जब आप DirectByteBuffer परत के अंदर DirectByteBuffer हैं, और यदि आप एक ही DirectByteBuffer से पढ़ रहे हैं और लिख रहे हैं तो वे बहुत तेज़ हैं, क्योंकि डेटा को कभी भी DirectByteBuffer सीमा पार नहीं करना पड़ता है।