2011-04-03 10 views
10

मैं स्मृति आवंटित करने के लिए AllocMem/GetMem/New routines का उपयोग करता हूं, फिर स्मृति जारी करने के लिए फ्रीमेम/निपटान दिनचर्या का उपयोग करें। लेकिन मैंने पाया (प्रक्रिया एक्सप्लोरर द्वारा) कि प्रक्रिया का स्मृति आकार कम नहीं हुआ है।मेमोरी को रिहा करने के लिए फ्रीमेम/डिस्पोजेक्ट का उपयोग क्यों करें, लेकिन कोई मेमोरी कम नहीं होती है?

यदि मैं ग्लोबलएलोक पीआरटी/हेपअलोक और ग्लोबलफ्रीपीआरटी/हेपफ्री एपीआई का उपयोग करता हूं, तो स्मृति आकार कम हो जाएगा।

type 
    TMyRec = record 
    Name: string; 
    TickCount: Cardinal; 
    Buf: array[0..1024 - 1] of byte; 
    end; 
    PMyRec = ^TMyRec; 

var 
    Form1: TForm1; 

implementation 

{$R *.dfm} 

procedure TForm1.FormDestroy(Sender: TObject); 
begin 
    FList.Free; 
end; 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    FList := TList.Create; 
    ReportMemoryLeaksOnShutdown := true; 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
var 
    i: Integer; 
    Size: Integer; 
    Rec: PMyRec; 
    Heap: Cardinal; 
begin 
    Size := SizeOf(TMyRec); 
    Heap := GetProcessHeap; 
    for I := 0 to 2000 - 1 do 
    begin 
    Rec := AllocMem(Size);        // Delphi routine 
    //GetMem(Rec, Size);        // Delphi routine 
    //New(Rec);           // Delphi routine 

    //Rec := GlobalAllocPtr(GPTR, Size);    // Windows API 
    //Rec := HeapAlloc(Heap, HEAP_ZERO_MEMORY, Size); // Windows API 
    FList.Add(Rec); 
    end; 
end; 

procedure TForm1.Button2Click(Sender: TObject); 
var 
    i: Integer; 
    Size: Integer; 
    Rec: PMyRec; 
    Heap: Cardinal; 
begin 
    Size := SizeOf(TMyRec); 
    Heap := GetProcessHeap; 
    for i := FList.Count - 1 downto 0 do 
    begin 
    Rec := PMyRec(FList.Items[i]); 
    FreeMem(Rec, Size);   // Delphi routine 
    //Dispose(Rec);    // Delphi routine 

    //GlobalFreePtr(Rec);   // Windows API 
    //HeapFree(Heap, 0, Rec);  // Windows API 
    end; 
    FList.Clear; 
end; 
+1

यह एक अच्छा प्रश्न (टीएम) है। समुदाय विकी होना चाहिए। –

उत्तर

24

इस प्रकार डेल्फी मेमोरी मैनेजर काम करता है - यह अपने स्वयं के मेमोरी कैश का समर्थन करता है ताकि यह हर मुक्त स्मृति को सिस्टम पर वापस न लौटाए, लेकिन इसे कैश में रखे। अगली बार जब यह कैश में अनुरोधित मेमोरी को खोजने के लिए पहले कोशिश करता है, तो सिस्टम में नहीं, यह स्मृति को आवंटित करता है। इससे मेमोरी आवंटन/डेलोकेशन तेज हो जाता है।

बीटीडब्ल्यू जीवन भर में प्रबंधित क्षेत्रों (पूर्व तारों, जैसा कि आपके उदाहरण में) के रिकॉर्ड के लिए FreeMem का उपयोग कभी नहीं करता - यह स्मृति रिसाव की ओर जाता है। इसके बजाय Dispose का उपयोग करें।

जीवन भर में प्रबंधित फ़ील्ड (आपके उदाहरण में टिप्पणी की गई पंक्ति) के रिकॉर्ड के लिए GetMem का भी उपयोग न करें - इससे उल्लंघन का उल्लंघन होता है। New का प्रयोग करें।

+5

+1। –

1

आप FreeMem कार्य करने के लिए आकार को निर्दिष्ट नहीं करना चाहिए:

यहाँ अपने परीक्षण कोड है। यह केवल एक पैरामीटर लेता है - सूचक। अन्यथा आपका कोड ठीक दिखता है। मुझे आश्चर्य है - आप नए के बजाय मॉलोक और मुफ्त का उपयोग क्यों कर रहे हैं और हटाएं/निपटान करें? या GetMem और FreeMem।

+7

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

+0

+1 "यह उत्तर उपयोगी है" –

11

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

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

+4

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

2

डेल्फी का मेमोरी मैनेजर वास्तव में पृष्ठों द्वारा स्मृति आवंटित/मुक्त करता है।

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