2009-06-10 15 views
10

मेरा आवेदन बड़ी मात्रा में स्मृति आवंटित करता है (कई गीगाबाइट्स के लाखों छोटी वस्तुएं) और लंबे समय तक इसे पकड़ता है।सी # कचरा संग्रह को दबाकर

  1. क्या .NET इस डेटा के माध्यम से जीसी करने के लिए समय बर्बाद कर रहा है?
  2. जनरल 2 जीसी कितनी बार होता है (वह जो सभी वस्तुओं की जांच करता है)?
  3. क्या इसकी आवृत्ति को कम करने या अस्थायी रूप से इसे होने से रोकने का कोई तरीका है?
  4. मुझे पता है कि जब मैं बड़ी मात्रा में स्मृति एकत्र करने के लिए तैयार हूं, तो क्या इसके लिए अनुकूलित करने का कोई तरीका है? मैं वर्तमान में जीसी कॉल कर रहा हूं। चयन(); GC.WaitForPendingFinalizers(); उस समय।

अद्यतन: पेर्फ काउंटर "जीसी में% समय" औसत 10.6% दिखा रहा है।

+0

कोड की वह पंक्ति केवल हर 3 मिनट के बारे में हिट हो जाती है, इसलिए शायद इसका कोई प्रभाव नहीं पड़ेगा। – Fantius

+1

संबंधित प्रश्न: [कम समय के लिए .NET कचरा संग्रह रोकें] (http://stackoverflow.com/questions/6005865), [वास्तविक समय में कचरा संग्रहण से कैसे बचें .NET अनुप्रयोग?] (Http: // stackoverflow .com/प्रश्न/85283) –

उत्तर

23

जब तक आप यह पुष्टि नहीं कर सकते कि कचरा कलेक्टर आपके एप्लिकेशन के प्रदर्शन को सक्रिय रूप से धीमा कर रहा है, तो आपको अपने रनटाइम पर्यावरण की कार्यक्षमता को अपंग करने के लिए कदम नहीं उठाएंगे।

आपके प्रश्न से निर्णय लेने के बाद, आपने पुष्टि नहीं की है कि जीसी एक समस्या है। मुझे गंभीरता से संदेह है कि यह है।

केवल अनुकूलित करने के लिए अनुकूलित करने की आवश्यकता है अनुकूलित करें।

+3

पेर्फ काउंटर "जीसी में% समय" औसत 10.6% दिखा रहा है। – Fantius

+0

यदि आपका आवेदन बहुत सारी वस्तुओं पर मंथन करता है, तो इसकी उम्मीद है कि आपके पास उच्च जीसी समय होगा। यदि आपने सी ++ में एक ही कोड लिखा है, तो आपके पास मेमोरी मैनेजर की दक्षता के आधार पर, स्मृति के हिस्सों को आवंटित करने, शून्य करने और मुक्त करने में लगभग उतना समय लगेगा। – jrista

+1

इसलिए दिया गया है कि मैं एक ही कक्षा में लाखों लोगों को आवंटित कर रहा हूं और फिर उनमें से एक बड़े हिस्से को एक साथ जारी कर रहा हूं, क्या सामान्य नए और त्याग से पालन करने के लिए एक बेहतर पैटर्न है? – Fantius

3

यह केवल (आमतौर पर) होता है जब जीसी को कुछ जीन 2 मेमोरी की आवश्यकता होती है (क्योंकि gen1 भरा हुआ है)। क्या आप इस अटकलें से पूछ रहे हैं, या क्या आपको वास्तव में जीसी के साथ आपके निष्पादन समय का एक बड़ा हिस्सा लेने में कोई समस्या है? यदि आपको कोई समस्या नहीं है, तो मेरा सुझाव है कि आप इस पल के लिए इसके बारे में चिंता न करें - लेकिन प्रदर्शन मॉनीटर के साथ इसकी नजर रखें।

+1

क्या मैं यह सोचने में गलत हूं कि जीसी जांच कर रहा है कि क्या 'पॉइंटर्स' उपयोग में हैं (या वे कितनी बार उपयोग किए जाते हैं), और प्रत्येक व्यक्तिगत ऑब्जेक्ट के आकार के साथ पूरी तरह से असंबंधित है? – DevinB

+1

जहाँ तक मुझे पता है, हाँ। दूसरी तरफ, यदि आपके पास कम बड़ी वस्तुएं हैं, तो उन्हें लाखों छोटे लोगों की तुलना में चिह्नित/स्वीप करने में कम समय लगेगा। हालांकि मैं इस प्रभाव को आपके डिजाइन को बताने से बचने की कोशिश करूंगा। –

+0

यह आपके डिज़ाइन को तब तक प्रभावित नहीं करेगा जब तक आपके पास 50/50 निर्णय न हो, उस स्थिति में आप उस विकल्प को चुनना चाहते हैं जो अनुकूलित करना आसान हो। पठनीयता और अन्य कारकों को मानना ​​बराबर है। मेरी राय में, अधिक जानकारी रखने के लिए हमेशा बेहतर होता है। – DevinB

9

System.Runtime.GCSettings.LatencyMode संपत्ति देखें।

ऐप.कॉन्फिग में जीसीएसरवर संपत्ति को सत्य में सेट करने से जीसी पर कटौती करने में भी मदद मिलेगी (मेरे मामले में 10 गुना कम जीसी सक्षम होने पर)।

+0

मैंने इसे कम लचीलापन पर सेट किया लेकिन मैंने कोई सुधार नहीं देखा। – Fantius

+0

GCLatencyMode.SustainedLowLatency ने मेरे लिए एक तेज़ पास-आरटी सिग्नल प्रोसेसिंग लूप की प्रतिक्रिया में सुधार करने में बहुत मदद की, धन्यवाद। – metao

9

आप अपने वस्तुओं में से किसी को अंतिम रूप देने स्थिर विधि का उपयोग करने से कचरा कलेक्टर को रोकने के कर सकते हैं:

GC.SuppressFinalize(*your object*) 

अधिक यहाँ जानकारी: link text

+1

जो संसाधन रिसाव को आमंत्रित करेगा और यह प्रश्न का समाधान नहीं करता है। –

+0

हां, जो संसाधन रिसाव को आमंत्रित करता है, लेकिन वास्तव में यह सवाल कुछ हद तक संबोधित करता है यदि आप जानते हैं कि वास्तव में कैसे काम करता है। – Joshua

+0

मैंने मूल प्रश्न का उत्तर दिया - यह तब से बदल गया है। मूल रूप से वह पूछ रहा था कि जीसी को अपनी बड़ी वस्तुओं की जांच करने से कैसे रोकें। चाहे यह एक अच्छा विचार है या नहीं, एक अलग मामला है। –

7

आप इस का उपयोग करते हुए प्रदर्शन मॉनिटर माप सकते हैं। ओपन परफॉर्म खोलें और .NET CLR मेमोरी से संबंधित प्रदर्शन काउंटर जोड़ें। ये काउंटर प्रक्रिया विशिष्ट हैं और उनके साथ आप विभिन्न पीढ़ियों के संग्रह और आकार की संख्या और "जीसी में% समय" के लिए अधिक स्पष्ट रूप से ट्रैक कर सकते हैं। यहाँ इस काउंटर के लिए पाठ की व्याख्या है: जीसी में

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

यदि आप अपने प्रोग्राम को चलाने के दौरान इन काउंटरों को देखते हैं, तो आपको अपने स्मृति निर्णयों के कारण जीसी की आवृत्ति और लागत का उत्तर देना चाहिए।

Here विभिन्न जीसी प्रदर्शन काउंटरों की अच्छी चर्चा है। ऐसा लगता है कि 10% सीमा रेखा ठीक है।

1

मेरा एएसपी.नेट आवेदन - बी 2 बी सिस्टम - पहले उपयोगकर्ता के आने पर 35-40 एमबी पर शुरू होता था। इतने मिनटों के बाद, आवेदन 180 या उससे अधिक उपयोगकर्ताओं के साथ 180 एमबी तक बढ़ने के लिए उपयोग किया जाता था। .नेट विकास सर्वोत्तम प्रथाओं और जीसी प्रदर्शन दिशानिर्देश पढ़ने के बाद मुझे पता चला कि समस्या मेरा आवेदन डिज़ाइन था। मैं एक बार में सहमत नहीं था।

मुझे डर था कि हम गलतियों को कितना आसान कर सकते हैं। मैंने कई विशेषताओं को छोड़ दिया और कुछ वस्तुओं को आसान बनाना शुरू कर दिया। अर्थ:

  1. बचें इतना पृष्ठों और बुद्धिमान और मिलनसार उपयोगकर्ता नियंत्रण (कार्यक्षमताओं जो वास्तव में सबसे प्रत्येक पृष्ठ इस पर नियंत्रण का उपयोग करता है के लिए मौजूद हैं की बहुत अधिक हैं) मिश्रण।

  2. आधार वर्गों पर सार्वभौमिक कार्यशीलताओं को रोकना बंद करें। कभी-कभी बेहतर दोहराया जाता है। विरासत लागत है।

  3. कुछ जटिल कार्यक्षमता पर मैंने सब कुछ एक ही कार्य पर रखा। हां, 100 लाइनों तक पहुंच रहा है। जब मैंने .NET प्रदर्शन मार्गदर्शन पर इस अनुशंसा को पढ़ा तो मुझे विश्वास नहीं था लेकिन यह काम करता है। कॉल स्टैक एक समस्या है, स्थानीय चर पर वर्ग गुणों का उपयोग एक समस्या है। कक्षा स्तर चर एक नरक हो सकता है ...

  4. जटिल आधार वर्गों का उपयोग करना बंद करें, 7 से अधिक लाइनों वाले कोई बेस क्लास मौजूद नहीं होना चाहिए। यदि आप पूरे ढांचे पर बड़ी कक्षाएं फैलते हैं, तो आपको समस्या होगी।

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

  6. कुछ परियोजनाओं को सहेजने के लिए, मुझे स्थिर राज्य पैटर्न पसंद है। मैंने असली दुनिया में सीखा लेकिन लेखक न्यागार्ड भी मेरी पुस्तक पर रिलीज करते हैं: रिलीज आईटी - डिज़ाइन और डिप्लॉयमेंट-रेडी सॉफ्टवेयर। वह इस तरह के दृष्टिकोण को स्थिर राज्य पैटर्न के रूप में कहते हैं। यह पैटर्न कहता है कि हमें निष्क्रिय संसाधनों को मुक्त करने के लिए कुछ चाहिए।

  7. आप मशीन कॉन्फ़िगरेशन फ़ाइल पर खेल सकते हैं। विशेषता स्मृति पर आप एक स्मृति पुन: उपयोग करने से पहले स्मृति के प्रतिशत को इंगित करेंगे।

  8. आप मशीन कॉन्फ़िगरेशन फ़ाइल पर भी खेलना चाहेंगे। इस विशेषता पर, जीसी मशीन व्यवहार (वर्कस्टेशन जीसी और सर्वर जीसी) को निर्देशित करेगा। यह विकल्प नाटकीय रूप से मेमोरी खपत व्यवहार को भी बदल सकता है।

जब मैंने इन वस्तुओं की परवाह करना शुरू किया तो मुझे बहुत सफलता मिली। उममीद है कि इससे मदद मिलेगी।

- 04-05-2014 में संपादित मैंने जीसी के नए संस्करणों के सुधार और एचटीएमएल 5 और एमवीसी ढांचे की प्रगति के कारण कई चीजों के बारे में अपना मन बदल दिया है।

+0

मेरा आवेदन समवर्ती उपयोगकर्ताओं के बारे में नहीं है। और मुझे नहीं लगता कि मैं किसी विरासत का उपयोग कर रहा हूं। कोई उपयोगकर्ता नियंत्रण नहीं है। कभी भी कुछ स्थिर हो सकता है, मैं इसे स्थिर बना देता हूं। मेरी प्रक्रिया कभी रीसायकल नहीं करती है। – Fantius

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