2010-07-07 16 views
5

मेरे पास .NET 3.5 SP1 का उपयोग करके लिखा गया एक एप्लिकेशन है जो बाहरी साइट से छवियों को डाउनलोड करता है और उन्हें उपयोगकर्ताओं को समाप्त करने के लिए प्रदर्शित करता है। दुर्लभ ocassions पर, मेरे उपयोगकर्ता OutOfMemory त्रुटियों का सामना कर रहे हैं क्योंकि वे भारी छवियों को डाउनलोड कर रहे हैं। कभी-कभी इन छवियों से जुड़े कच्चे डेटा बड़े होते हैं, लेकिन अधिकतर, छवियों के आयाम बहुत बड़े होते हैं। मुझे एहसास है कि मैं कभी भी इस तथ्य को पाने में सक्षम नहीं हो सकता कि इन ओओएम त्रुटियों को विशेष छवियों के लिए फेंक दिया गया है। यह बहुत उपयोगी होगा, हालांकि, अगर मैं किसी भी तरह से छवि लोड करने का प्रयास करने से पहले किसी विशेष छवि को लोड करने से ओओएम मुद्दे को लोड कर सकता हूं तो यह निर्धारित कर सकता है।यह पता लगाने के लिए कि कोई छवि लोड करने से .NET में आउटऑफमेमरी अपवाद फेंक देगा?

छवियों के लिए डेटा स्ट्रीम में लोड किया गया है, और फिर छवि स्वयं को सिस्टम में बदल दिया जाता है। ड्रॉइंग। सिस्टम को कॉल करके इमेज। ड्रॉइंग.इमेज.फ्रेमस्ट्रीम (स्ट्रीम)। मेरे पास पहले डिस्क पर इन छवियों को संग्रहीत करने का विकल्प नहीं है। उन्हें स्मृति के माध्यम से लोड किया जाना चाहिए।

अगर किसी के पास कोई सुझाव या सुझाव है जो मुझे यह पता लगाने की अनुमति देगा कि एक छवि लोड करने से ओओएम अपवाद हो जाएगा, तो मैं इसकी बहुत सराहना करता हूं।

+0

"छवियों के लिए डेटा स्ट्रीम में लोड किया गया है" ... जादू द्वारा, या कैसे? – Will

+0

@Will - "बाहरी साइट से डाउनलोड छवियां" –

+0

@ जोएल तो उसे स्ट्रीम मिलती है, फिर उस स्ट्रीम को मेमोरीस्ट्रीम में फ़ीड करता है, फिर उस स्ट्रीम को किसी छवि के साथ उपयोग करता है? और वह सोच रहा है कि वह स्मृति से बाहर क्यों चल रहा है? क्यों न केवल मूल धारा का उपयोग करें और मध्य आदमी को काट लें? क्या मैं पागल हूँ? – Will

उत्तर

1

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

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

1

आप इस सवाल पर लग सकता है और देखो अगर यह मदद करता है: How do I reliably get an image dimensions in .NET without loading the image?

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

नकारात्मक तरफ, ऐसा लगता है कि आपको प्रत्येक फ़ाइल प्रकार की बाइनरी को विघटित करने के लिए एक विधि लिखनी होगी जिसे आप संभालना चाहते हैं।

+0

हाँ, हम इस दृष्टिकोण का उपयोग करने के बारे में सोच रहे थे। हमारी सबसे बड़ी चिंता अभी भी है कि हमारे पास सटीक रूप से भविष्यवाणी करने का एक अच्छा तरीका नहीं है कि कितनी मेमोरी सिस्टम है। ड्रॉइंग.इमेज.फॉम इमेज का उपयोग किया जाएगा। हमें किसी भी छवि प्रकार का समर्थन करने की आवश्यकता है जो .NET मूल रूप से समर्थन करता है। प्रत्येक फ़ाइल प्रकार की बाइनरी को विघटित करने की आवश्यकता के शीर्ष पर .NET का समर्थन करता है, हमें किसी भी तरह से ऐसी विधि के साथ आने की आवश्यकता होती है जो उन छवियों को लोड होने पर उपयोग की जाने वाली स्मृति की सटीक भविष्यवाणी करता है। ऐसा लगता है कि डेवलपर्स की एक पूरी टीम महीनों तक काम कर सकती है! :( – Keith

1

आपके पास चिकन-एंड-अंडे की समस्या है। किसी प्रकार का अनुमान लगाने के लिए, आपको छवि के आकार को जानने की आवश्यकता है। जब तक आप इसे लोड नहीं करते हैं तब तक आप आकार को नहीं जानते हैं।

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

ध्यान दें कि यह ओओएम अपवाद उसी तरह का ओओएम नहीं है जब आप बहुत अधिक प्रबंधित स्मृति का उपयोग करते हैं। यह वास्तव में एक जीडीआई + अपवाद है और आप आसानी से इसे ठीक कर सकते हैं। बस अपवाद पकड़ें और "क्षमा करें, यह नहीं कर सका" संदेश प्रदर्शित करें।

यदि आप किसी भी तरह के सामने के आकार को जानते हैं तो आप काफी सुरक्षित रूप से सामने आ सकते हैं कि चौड़ाई * ऊंचाई * 4> 550 एमबी 32-बिट प्रोग्राम में काम नहीं करेगा। थोड़ी देर के लिए दौड़ने के बाद यह सीमा जल्दी से नीचे जाती है।

1

यदि आप बाहरी साइट से छवियों को डाउनलोड कर रहे हैं, और बाहरी साइट Content-Length HTTP शीर्षलेख सेट करती है, तो आप यह अनुमान लगाने में सक्षम हो सकते हैं कि स्ट्रीम स्ट्रीम करने से पहले छवि मेमोरी में फिट होने जा रही है .. ।

+0

हमें सामग्री-लंबाई वाला हेडर मिलता है। हालांकि, डेटा का तीव्र भौतिक आकार एक बड़ी भविष्यवाणी नहीं है कि फ़ाइल कितनी मेमोरी लोड हो रही है। मैंने उन फ़ाइलों को देखा है जो 800 एमबी से अधिक की चबाने वाली 5 एमबी से कम हैं जब लोड हो गया क्योंकि उनके आयाम इतने बड़े हैं। – Keith

4

आप स्मृति उपलब्धता की जांच के लिए MemoryFailPoint कक्षा का उपयोग कर सकते हैं।

बेस्ट

+2

कृपया सभी को यह बताएं कि यह कैसे काम करता है, यह FAR द्वारा "कोशिश/पकड़" तरीके से बड़ी मेमोरी आवंटन से निपटने का सबसे अच्छा तरीका है। – Spence

+0

मैं इसे देख लूंगा। एक त्वरित नज़र मुझे लगता है कि मुझे ऐसा नहीं हो सकता है जैसा कि मुझे दस्तावेज के रूप में चाहिए, मुझे लगता है कि मुझे "स्मृति की मेगाबाइट्स की संख्या निर्दिष्ट करने की आवश्यकता होगी जिसे ऑपरेशन का उपयोग करने की उम्मीद है"। समस्या यह है कि मुझे नहीं पता कि जीडीआई + कितनी मेमोरी जा रही है जब यह System.Drawing.Image.FromStream का उपयोग कर छवि लोड करता है तो इसका उपयोग करने के लिए। – Keith

1

मैं पहले से ही @Vagaus जवाब के साथ सहमत हो गए हैं, लेकिन मैं जोड़ने के लिए है कि आप केवल एक बार बफर आवंटित और यह पुन: उपयोग करने की कोशिश करनी चाहिए चाहता था। यदि आप लगातार बड़े बफर आवंटित और रिलीज़ कर रहे हैं तो आप ढेर पर विखंडन के कारण निश्चित रूप से ओओएम मुद्दे पर पहुंच जाएंगे।

+0

हम इन तकनीकों का उपयोग करते समय इस तकनीक का उपयोग करते हैं। हालांकि, मुझे पूरा यकीन है कि System.Drawing.Image.FromImage का उपयोग करता है यह अपने आंतरिक बफर जो वैसे भी ढेर विखंडन की ओर जाता है। – Keith

+0

क्या आप जीडीआई सामान पर सभी डिस्पोजेर्स को बुला रहे हैं? मुझे पहले जला दिया गया है, जीडीआई + पुस्तकालयों में लगभग हर छोटी कक्षा में अप्रबंधित स्मृति को जारी करने के लिए एक निपटान कॉल की आवश्यकता होती है। शायद आप इस वजह से स्मृति लीक कर रहे हैं, ओओएम का कारण बन रहा है? – Spence

+0

मुझे विश्वास है कि हम अपनी सभी वस्तुओं को सही तरीके से निपट रहे हैं। हमारे पास ऐसे उपयोगकर्ता हैं जो सामान्य आकार की छवियों को देखने में घंटों खर्च कर सकते हैं और मेमोरी पदचिह्न स्थिर रहता है। विशाल आयामों के साथ केवल मौलिक छवि है जो सभी शेष स्मृति को गोद लेती है। – Keith