2012-05-21 14 views
8

कुछ एसिंक्रोनस टीसीपी सर्वर कोड में, कभी-कभी एक त्रुटि होती है जो प्रक्रिया को पूरे सिस्टम की स्मृति का उपभोग करने का कारण बनती है। लॉग, इवेंट व्यूअर और कुछ MS docs को देखकर समस्या तब होती है जब "कॉलिंग एप्लिकेशन असीमित आईओ को एक ही क्लाइंट को कई बार कॉल करता है तो रिमोट क्लाइंट I/I के अंत को रोकता है तो आप एक ढेर विखंडन और निजी बाइट वृद्धि देख सकते हैं। ओ "जिसके परिणामस्वरूप मेमोरी उपयोग और सिस्टम की पिनिंग में स्पाइक्स होते हैं। थ्रेडिंग। ओवरलैप्डडेटा स्ट्रेट और बाइट एरेज़।एसिंक्रोनस टीसीपी .NET कोड को पूरे सिस्टम के संसाधनों का उपयोग करने से कैसे रोकें

केबी आलेख का प्रस्तावित समाधान "अपने असीमित आईओ के साथ बकाया बकाया राशि (या तो भेज या प्राप्त) की ऊपरी सीमा निर्धारित करना है।"

कोई यह कैसे करता है? क्या यह बाइट [] का जिक्र है जो BeginRead में भेजा जाता है? तो क्या समाधान केवल सैटफोर के साथ बाइट [] के साथ लपेट रहा है?

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

संपादित 2: इस महान answer पर आया। असल में यह दिखाता है कि वस्तुओं को मैन्युअल रूप से अनपिन कैसे करें। और जब एसिंक्रोनस टीसीपी कोड दृश्यों के रनटाइम नियमों के पीछे पिनिंग करता है, तो उपयोग से पहले प्रत्येक बफर को स्पष्ट रूप से पिन करके, अंत में ब्लॉक के अंत में या अंत में अनपिन करना संभव हो सकता है। मैं अब इसे समझने की कोशिश कर रहा हूं ...

+0

संभावित डुप्लिकेट: http://stackoverflow.com/questions/236171/net-does-not-have-reliable-asynchronouos-socket-communication कि – Dennis

+0

सेमाफोर साथ BeginRead करने के लिए कॉल लपेटकर बारे में है। – mikalai

+0

शायद यह कोड को प्रोफाइल करने का एक अच्छा कारण है ... – gsscoder

उत्तर

3

समस्या को हल करने का एक तरीका पूर्व-आवंटित बफर और एसिंक संचार में उपयोग की जाने वाली अन्य डेटा संरचनाओं द्वारा किया जाता है। यदि आप स्टार्टअप पर प्रीलोकेट करते हैं, तो कोई विखंडन नहीं होगा, क्योंकि स्मृति प्राकृतिक रूप से ढेर के उसी क्षेत्र में रहती है।

मैं ReceiveAsync/SendAsync एपीआई का उपयोग करना चाहिये 3.5 एसपी 1, जो आप कैश करने के लिए या पूर्व आवंटित, दोनों SocketAsyncEventArgs संरचना और स्मृति बफर SocketAsyncEventArgs.Buffer संपत्ति में संग्रहीत पुराने BeginXXX/EndXXX एपीआई के विपरीत जो केवल अनुमति देने के लिए अनुमति देता है नेट को जोड़ा गया कैशिंग या मेमोरी बफर को आवंटित करना।

पुराने एपीआई का उपयोग करने से महत्वपूर्ण सीपीयू लागत भी हुई, क्योंकि एपीआई ने आंतरिक रूप से विंडोज ओवरलैप्ड I/O संरचनाओं को आंतरिक रूप से बनाया। नई एपीआई में यह SocketAsyncEventArgs के भीतर होता है, और इसलिए इन वस्तुओं को पूल करके, सीपीयू लागत केवल एक बार भुगतान की जाती है।

पिनिंग पर आपके अपडेट के बारे में: पिनिंग एक कारण के लिए है, अर्थात् जीसी को डीफ्रैग्मेंटेशन के दौरान बफर को स्थानांतरित करने से रोकने के लिए। मैन्युअल रूप से अनपिन करके, आप स्मृति भ्रष्टाचार का कारण बन सकते हैं।