2009-10-08 12 views
5

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

मुझे आश्चर्य हुआ कि कोर ऑब्जेक्ट्स शुरू करने के बाद यह लगभग 40 एमबी रैम का उपयोग कर समाप्त होता है।

मैंने परीक्षण किया और पता चला कि ऑब्जेक्ट प्रारंभ करने के बाद 30 एमबी से अधिक आवंटित किया गया है, लेकिन मैं इस धारणा के तहत था कि मेरी वस्तुओं के आकार को देखते हुए, कुछ सौ किलोबाइट से अधिक नहीं खाया जाना चाहिए था।

क्या मैंने कुछ गलत किया है या नेट कोड स्वाभाविक रूप से मूल कोड अनुप्रयोगों की तुलना में स्मृति गहन है?

+4

रनटाइम भारी है। –

+2

मैं आपसे सहमत हूं। मुझे लगता है कि आप कुछ गलत कर रहे हैं। –

+0

क्या आप कुछ नमूना कोड पोस्ट कर सकते हैं?मुझे लगता है कि यह समझने में बहुत मदद करेगा कि यह कोड है जो इसे अकेले हाथ से उत्पन्न करता है या रन टाइम –

उत्तर

7

अपने मेमोरी उपयोग को देखने के लिए टास्क मैनेजर का उपयोग करना बेहद गलत हो सकता है।

इसके बजाय, एक उचित स्मृति रूपरेखा उपकरण हड़पने (dotTrace बहुत अच्छा है, और एक 10 दिन परीक्षण है) और समय आपके वास्तविक स्मृति की खपत को देखने के लिए ले लो।

चीजों की तरह मैं अपने खुद के कोड में देखा है

  • underestimating कितनी स्मृति मैं वास्तव में उपयोग कर रहा हूँ (अलग वस्तुओं ठीक से गिनती नहीं, सूचियों के लिए के लिए "अतिरिक्त" क्षमता की अनुमति नहीं दे) शामिल
  • क्षणिक वस्तुओं के लिए रखते हुए संदर्भ है कि मैं
  • की जरूरत नहीं है ऑपरेशन के दौरान बनाई गई क्षणिक वस्तुओं है कि अभी तक कचरा एकत्र
  • आवंटित नहीं की गई स्मृति के लिए अनुमति नहीं नहीं किया गया है के लिए अनुमति नहीं है - स्मृति है कि ओएस से दावा किया गया है (और यह टास्क मैनेजर में प्रक्रिया के एक हिस्से के रूप में दिखाया गया है) लेकिन जिसे किसी भी ऑब्जेक्ट को अभी तक आवंटित नहीं किया गया है
  • थ्रेड स्टैक्स के लिए अनुमति नहीं दे रहा है (प्रत्येक थ्रेड को स्वयं का ढेर मिल जाता है; .NET अनुप्रयोग हमेशा बहु-थ्रेडेड होते हैं क्योंकि ढांचा स्वयं के कई धागे बना सकता है)।
2

यह हमेशा भाषा के बारे में नहीं है, आमतौर पर इसका उपयोग कैसे किया जाता है।

अच्छा कोड किसी भी भाषा में कुशलता से स्मृति का उपयोग कर सकते हैं।

बुरा कोड हर

+4

ठीक है, केवल आधा सच है। इस मामले में भाषा/रनटाइम * वास्तव में काफी मायने रखती है। -1 –

+1

सही, अगर आपको स्मृति के कुछ सौ के बारे में परवाह है, तो सी अक्सर एक बेहतर विकल्प होता है। –

+1

मेरे उत्तर के बारे में क्या सच नहीं है? (जोर के लिए थोड़ा अपडेट किया गया) –

12

आप किस तरह तय किया था कि स्मृति कितना इस्तेमाल किया गया था भाषा में अकुशलता से स्मृति का उपयोग करेंगे? .NET अनुप्रयोगों को उत्सुकता से उनकी स्मृति की तुलना में अधिक स्मृति को आरक्षित करने के लिए जाना जाता है, जब तक कि बहुत सारी मेमोरी उपलब्ध हो, और स्मृति पर स्मृति चलाने के लिए सिस्टम को स्मृति को वापस छोड़ दें।

मुझे लगता है कि आपको this MSDN article में कुछ पॉइंटर्स मिल सकते हैं।

+0

कार्य प्रबंधक का उपयोग करके - यह इंगित करने के लिए धन्यवाद कि यह वैध संख्या – PiotrK

2

नेट रनटाइम का एक निश्चित बड़ा ओवरहेड है - हमने पाया है कि यहां तक ​​कि सरल अनुप्रयोग भी अधिक स्मृति का उपयोग करते हैं जो सी ++ में लिखे गए समान अनुप्रयोगों का उपयोग करते हैं। सौभाग्य से इस ओवरहेड को शोर में जल्दी से हटा दिया जाता है क्योंकि समग्र कोड का आकार बढ़ जाता है। दूसरा कारक कचरा संग्रह का है, कचरा कलेक्टर "जब भी" चलाता है, इसलिए सी ++ की तुलना में, स्मृति आवंटन आमतौर पर तुरंत मुक्त नहीं होते हैं, बल्कि जब ऐसा करने की आवश्यकता महसूस होती है।

5

उन दिनों में जहां हमारे पास मशीन पर कई जीबी रैम है, यह विचार है कि आपके जैसे उपयोगकर्ता का सामना करने वाला ऐप आम तौर पर सी # में बनता है, केवल कुछ 100K रैम का उपयोग करना चाहिए। आपके सिस्टम पर कोई भी अप्रयुक्त राम बर्बाद हो गया है।

इस बात को ध्यान में रखते हुए, सी # सी ++ से बहुत अलग रणनीति का उपयोग करके स्मृति आवंटित करता है, जैसे कि बड़े भाग आवंटित किए जाते हैं और कम से कम मुक्त होते हैं।

उस ने कहा, 40 थोड़ा अधिक लगता है। मुझे बहुत सरल कंसोल ऐप्स के लिए 10-14 एमबी के करीब कुछ उपयोग किया जाता है। शायद राम बनाने का एक फॉर्म है, या शायद मैं ढांचे के एक अलग संस्करण (2.0) पर हूं।

+4

नहीं हो सकता है "आपके सिस्टम पर कोई भी अप्रयुक्त राम बर्बाद हो गया है।" कोई भी रैम जो मेरा ऐप होगिंग नहीं कर रहा है, शायद किसी अन्य ऐप या ओएस द्वारा बेहतर उपयोग के लिए रखा जा सकता है। –

+2

लेकिन इसे 'गले लगाया नहीं जा रहा है', इसे एक लालची फैशन में रनटाइम द्वारा आवंटित किया जा रहा है। यदि आवश्यक हो तो रनटाइम इसे ओएस पर भी वापस कर सकता है। –

+0

मुख्य कारणों में से एक लिनक्स विंडोज़ से बेहतर प्रदर्शन करता है क्योंकि यह सभी अप्रयुक्त स्मृति को डिस्क कैश के रूप में उपयोग करता है, जो पढ़ने की गति में काफी सुधार करता है (जो खाली फ़ाइलों को झंडे के रूप में उपयोग करने के लिए निक्स मुहावरे के कारण बहुत जरूरी है)। यदि आपका ऐप इस मेमोरी को हॉग करता है, तो वह ऐसा नहीं कर सकता है। – rmeador

2

मैं कहूंगा कि जब तक आपके पास बहुत RAM उपयोग के बारे में चिंता करने का अच्छा कारण नहीं है, नहीं। अनुकूलन की तरह, आपको केवल यह अनुकूलित करना चाहिए कि ग्राहक/अंत उपयोगकर्ता को ऐसा करने की आवश्यकता है। मुझे विश्वास नहीं है कि उपयोगकर्ता इन दिनों स्मृति से इतने बाध्य हैं (जब तक कि आप एक एम्बेडेड सिस्टम के बारे में बात नहीं कर रहे हों) कि वे 38 एमबी गायब होने के बारे में ज्यादा ध्यान देने या देखभाल करने जा रहे हैं।

+0

यदि मैं एकल मॉड्यूल लिखने के बाद 40 मेगा का उपयोग करता हूं और एप्लिकेशन होगा ... मान लें कि 20 - 30 ऐसे मॉड्यूल पूर्ण डेटा सेट से गुणा करते हैं, मुझे अच्छी तरह से चिंता है कि मैं 512 मेगाबाइट रैम – PiotrK

+1

में नहीं बनाऊंगा @ PiotrK: हाँ, अगर यह इतना आसान था, लेकिन यह नहीं है। .NET अनुप्रयोग रनटाइम द्वारा प्रबंधित किए जाते हैं। उपयोग की गई स्मृति की मात्रा सीधे आपके कोड के साथ क्या कर रही है उसे प्रतिबिंबित नहीं करती है, आपकी धारणाएं गलत हैं। –

+0

पियट्रैक: लेकिन आप नहीं करेंगे। स्मृति उपयोग मॉड्यूल की संख्या या आकार के साथ रैखिक रूप से स्केल नहीं करता है। आप .NET रनटाइम के लिए एक बड़ी हिट लेते हैं, लेकिन आप केवल एक बार हिट करते हैं। आप देख सकते हैं कि एक मॉड्यूल के साथ आप 40 एमबी का उपभोग कर रहे हैं, लेकिन प्रत्येक बाद के मॉड्यूल में केवल एमबी का एक और जोड़ा जोड़ा जा सकता है (इस पर निर्भर करता है कि यह कितनी मेमोरी आवंटित करता है)। – itowlson

-8

एक त्वरित calc आप शायद चारों ओर 340k वस्तुओं का आवंटन कर रहे हैं कर (32 बिट पर एक सांत्वना क्षुधा के लिए हमेशा की तरह c12MB हिट घटाकर, उफ़ स्टीव!) और देख [वस्तु + तो प्रति 8bytes खा एक विशिष्ट परिदृश्य के संदर्भ को हटाने क्रम और System.Object कचरे के अन्य सामान्य संदिग्धों] संदर्भ प्रकार के लिए फूला हुआ क्रम तकनीक कॉपीराइट @ Sun.com ..

कोशिश और डिजाइन द्वारा मूल्य प्रकार के लिए के लिए कुछ/structs यदि संभव हो .. यदि आप नहीं कर सकते, कठिन, अपने उपयोगकर्ताओं को 10 से अधिक .NET ऐप्स चलाने के लिए न कहें या उनकी मशीन C64 से धीमी महसूस करेगी। यदि यह आपको बेहतर महसूस करता है, तो WPF या Silverlight आज़माएं और कुछ बटन और चमकदार एनिमेशन के लिए c100MB जुर्माना महसूस करें।

(downvote महसूस)

+2

यह भयानक, गलत सलाह है। -1 –

+4

इतना बुरा है कि मुझे इसे दो बार कहना है। –

+0

निश्चित रूप से, सुनिश्चित करें कि आप सीएलआर निष्पादन इंजन डिज़ाइनर ब्लॉग पर जाएं और प्रविष्टियों को पढ़ें कि उन्होंने मूल्य प्रकार तकनीक के लिए क्यों चुना है, वास्तव में सरणी आवंटन ताकि वे 2001 के बाद से महसूस किए गए 2 ऐप्स में इस प्रकार के ओवरहेड से बच सकें। बीटीडब्ल्यू , उस टीम पर, अधिकांश किया गया था, भाग गया, Google मातृत्व और यह सिर्फ रास्ता फर्श रखता है .. –

0

आप स्मृति यह भ्रामक हो सकता है को देखने के लिए कार्य प्रबंधक का उपयोग कर रहे हैं। वर्किंग सेट प्रक्रिया में मैप किए गए वर्चुअल मेमोरी की मात्रा है। यह आवश्यक नहीं है कि आपका एप्लिकेशन कितना उपयोग कर रहा है - यह विशेष रूप से .NET के कचरे से एकत्रित वातावरण में सच है। चूंकि आपका प्रोग्राम स्मृति आवंटित करता है। .NET CLR/GC आमतौर पर ओएस से इसकी आवश्यकता से अधिक मेमोरी का अनुरोध करेगा ताकि वह उस मेमोरी को भविष्य में आपके प्रोग्राम में प्रबंधित ऑब्जेक्ट्स को कुशलता से आवंटित कर सके।

एक त्वरित और गंदा तरीका (बहुत गंदा) यदि यह आप 0. यह Win32 में SetProcessWorkingSetSize उपयोग करने का प्रयास है और इस प्रक्रिया को मैप किया पृष्ठों की राशि ट्रिम करने के समान है के लिए Process.MaxWorkingSet गुण सेट करने के लिए है प्रभावित कर रहा है देखने के लिए। यदि आप तुरंत स्मृति उपयोग में एक बूंद देखते हैं तो आप जानते हैं कि क्या हो रहा है। हालांकि, जैसे ही आप जीसी/सीएलआर के माध्यम से फिर से स्मृति आवंटित करना शुरू करते हैं, यह बैक अप जाएगा - और आमतौर पर यह एक अच्छी बात है। वास्तव में आपको इसके बारे में चिंता नहीं करनी चाहिए और जीसी को इसे सही तरीके से करने का मौका देना चाहिए।

दोनों के लिए अपने कार्यक्रम के स्मृति उपयोग का अनुकूलन और एक बेहतर कैसे स्मृति आवंटन CLR मैं सुझाव है कि आप dotTrace (मेरी प्राथमिकता) के साथ खिलवाड़ शुरू में काम करता है का विचार है, Ants Profiler (जो संयोग से publishes a cool video on this topic here) मिलता है। CLRProfiler भी दिलचस्प है, लेकिन यह इन दिनों थोड़ा सा दिनांक है, लेकिन यह मुफ़्त है।

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