2012-04-05 20 views
6

मैं एक डेल्फी एप्लिकेशन बना रहा हूं जो वैज्ञानिक सिमुलेशन करता है। जटिलता में बढ़ रहा है & में अब कई इकाइयां और रूप शामिल हैं।डेल्फी: EOutOfMemory त्रुटि को कैसे ढूंढें और ठीक करें?

मैं प्रत्येक बार चलाने के दौरान EOutOFMemory त्रुटियों को प्राप्त करना शुरू कर रहा हूं। ऐसा लगता है कि मैं अस्थायी रूप से एक फ़ंक्शन के भीतर संस्करण के ऐरे का उपयोग करने के दौरान या उसके बाद होता हूं। वास्तव में गूंगा सवाल पूछने के जोखिम पर, "संस्करण की सरणी" परेशानी के लिए पूछ रही है? (मैं सबकुछ स्ट्रिंग में बदल सकता हूं, लेकिन सिद्धांत में संस्करण की सरणी बहुत सारी चीजों को बचाती है)।

हमलावर सरणी उपयोग हो सकता है:

Function TProject.GetCurrentProjParamsAsArray(LProjectName, LProjectType : ShortString): ArrayOfVariant; 
Var 
    ArrayIndex : Word; 
begin 
    SetLength (Result,54); 
    ArrayIndex := 0; 
    Result [ArrayIndex] := LProjectName;  Inc(ArrayIndex); 
    Result [ArrayIndex] := LProjectType;  Inc(ArrayIndex);     // this structure makes it easier to add extra fields in the DB than hard coding the array index!! 
    Result [ArrayIndex] := FileTool.DateTimeForFileNames ; Inc(ArrayIndex); 
    Result [ArrayIndex] := SiteAndMet. SiteName   ; Inc(ArrayIndex); 
    Result [ArrayIndex] := SiteAndMet. PostCode   ; Inc(ArrayIndex); 
    Result [ArrayIndex] := SiteAndMet. MetFileNamePath  ; Inc(ArrayIndex); 
    Result [ArrayIndex] := SiteAndMet. SiteLat    ; Inc(ArrayIndex); 
    Result [ArrayIndex] := SiteAndMet. SiteLong   ; Inc(ArrayIndex); 
    Result [ArrayIndex] := SiteAndMet. SiteAlt    ; Inc(ArrayIndex); 
    Result [ArrayIndex] := SiteAndMet. TZoneIndex   ; Inc(ArrayIndex); 
    Result [ArrayIndex] := SiteAndMet. TZoneHours   ; Inc(ArrayIndex); 
    Result [ArrayIndex] := SiteAndMet. TZoneMeridian  ; Inc(ArrayIndex); 
    Result [ArrayIndex] := SiteAndMet. Albedo    ; Inc(ArrayIndex); 
    Result [ArrayIndex] := SiteAndMet. ArrayTilt   ; Inc(ArrayIndex); 
    Result [ArrayIndex] := SiteAndMet. ArrayAzimuth  ; Inc(ArrayIndex); 

कार्य प्रबंधक में - शिखर स्मृति उपयोग 42MB है, वीएम 31M है और मैं रन प्रति ~ 90,000 पेज दोष हो रही है। (साथ 3GB राम एक XP मशीन पर)

किसी को अपने आवेदन के भीतर विभिन्न घटकों द्वारा स्मृति के उपयोग की निगरानी पर किसी भी सामान्य युक्तियाँ है? या इस त्रुटि के कारण का पता लगाने पर?

हाल ही में मैं मुख्य परियोजना डेटा को एडीओ डीबी, का उपयोग करने के लिए सीएसवी के रूप में संग्रहीत करने से चला गया हूं, साथ ही साथ मैंने betweem स्ट्रिंग और सिंगल/डबल को हर समय परिवर्तित करने के बजाय वेरिएंट डेटा प्रकार का उपयोग शुरू कर दिया है।

मैं विभिन्न स्मृति बचत युक्तियाँ, जैसे जहां व्यावहारिक मैं Application.CreateForm (TProject, परियोजना) को हटा दिया है मैं मिल सकता है का पालन किया है; .dpr से बयान और गतिशील रूप से उन्हें बनाते हैं। (वैसे भी जहां फॉर्म का उपयोग ज्यादातर समय किया जा रहा है)। आम तौर पर मैं सबसे छोटी व्यावहारिक डेटाप्रकार (बाइट, shortstring, आदि) का उपयोग करें और, 'सार्वजनिक' चर & कार्यों

कोई सुझाव बहुत स्वागत के उपयोग को कम करने के ब्रायन

+0

आप पृष्ठ दोष प्राप्त करने की उम्मीद करते हैं। इसके बारे में चिंता मत करो। एक 'संस्करण का सरणी' बहुत बुरा नहीं लगता है। आखिरकार आपके पास केवल सरणी में 54 तत्व हैं। 42 एमबी तुच्छ है। यह जानकारी देने के लिए लगभग असंभव है कि इस जानकारी को क्या चल रहा है। –

+0

परिभाषित किया गया है 'ArrayOfVariant'? क्या आप सरणी या केवल साधारण प्रकार में वस्तुओं को संग्रहित कर रहे हैं? – RRUZ

+0

ArrayOfVariant एक अलग उपयोगिता इकाई में यानी ArrayOfVariant = संस्करण की सरणी कार्यों के बीच जब से तुम नहीं कर सकते पास (परिभाषित किया गया है 'की सरणी ....'; यह केवल डबल और स्ट्रिंग मान शामिल – SolarBrian

उत्तर

2

मुझे संदेह है कि आप जो कोड दिखा रहे हैं, वह समस्या का स्रोत है। यह शायद एक जगह है जहां एक लक्षण होता है।

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

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

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

+0

हम्म एकटाइम भी कोशिश करेगा, धन्यवाद! – SolarBrian

+0

एकटाइम काफी निष्कासित है, पिछले परीक्षण में मुझे बहुत मदद मिली। Http://www.prodelphi.de/ – LaBracca

+0

इसके बजाय नेक्सस गुणवत्ता सूट आज़माएं, या एक नि: शुल्क विचार के लिए, पूर्ण डीबग मोड में फास्टएमएम का उपयोग करें, और यह निर्धारित करने के लिए हीप डंप का उपयोग करें कि आपकी मेमोरी का उपयोग किस प्रकार किया जा रहा है। –

10

EOutOfMemory तब होता है जब स्मृति प्रबंधक स्मृति का एक contigious ब्लॉक नहीं मिल सकता है दिए गए आवंटन अनुरोध के लिए। तो आप या तो 1 हैं) आप अपेक्षा से अधिक मेमोरी आवंटित कर रहे हैं, 2) स्मृति को लीक करना जिसे आपने सफलतापूर्वक आवंटित किया है, या 3) स्मृति (आवश्यक रूप से लीक नहीं) स्मृति को स्मृति प्रबंधक को समय के साथ अधिक से अधिक स्मृति आवंटित करना है।

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

+2

विखंडन एक प्रशंसनीय विवरण है के लिए कुख्यात है। लेकिन पता है जो आवंटन शायद ही कभी मदद करता है विफल रहता है यह बताएं कि स्मृति खंडित हो गया। –

+0

, लेकिन कभी कभी यह कर सकते हैं, कोड है कि क्रैश हो रहा है अगर एक ही कोड जो खंडित है। –

+0

आह, अपवाद लॉगिंग फ्रेमवर्क बहुत आसान है, धन्यवाद मैं ' कोशिश करेंगे! – SolarBrian

2

क्या आपने फास्टमेम मेमोरी मैनेजर का पूरा संस्करण स्थापित किया है? यह आपको स्मृति प्रबंधन में त्रुटियों को ट्रैक करने में मदद कर सकता है। देखें कि आप कुछ लीक कर रहे हैं या नहीं।

यदि आपके पास रिसाव नहीं है तो आपके पास एक बेहद चरम विखंडन समस्या है, आपको ऑब्जेक्ट्स को आवंटित/हटाने के बजाय वस्तुओं का पूल बनाए रखकर इसका सामना करना होगा।

+0

फास्टएमएम - धन्यवाद का प्रयास करेंगे! – SolarBrian

2

OutOfMemory अपवाद आप सभी वस्तुओं निर्माण पर देखने के लिए और न सिर्फ जहां अपवाद उठाया जाता है की जरूरत है की एक कारणों का पता लगाने के लिए।

यूरेकालॉग जैसे तीसरे भाग टूल आपको एप्लिकेशन पर तत्काल सभी ऑब्जेक्ट दिखा सकते हैं और सही तरीके से निपटान नहीं कर सकते हैं। आप FreeAndNil प्रक्रिया के साथ आखिरकार ब्लॉक का प्रयास करके उन्हें सही करने का प्रयास कर सकते हैं।

+0

मिमीएम, मैंने हाल ही में शायद ही कभी इस्तेमाल किए गए रूपों से मेमोरी ओवरहेड को कम करने के लिए बहुत सारे निर्माण/नि: शुल्क जोड़े हैं, इसलिए यह समस्या हो सकती है। धन्यवाद! – SolarBrian

2

मेमोरी लीक की तरह लगता है।

मैं हमेशा के लिए मेरे डिबग बनाता है परियोजना स्रोत फ़ाइल के लिए एक

{$IFDEF DEBUG} 
    ReportMemoryLeaksOnShutdown := DebugHook <> 0; 
    {$ENDIF} 

जोड़ें।

यह एक अच्छा संकेत देता है कि मैंने प्रोग्राम कितनी अच्छी तरह बनाया है।

+0

+1 @andy_k लेकिन आप इसे कहां जोड़ते हैं? – Mawg