क्या प्रोग्रामिक रूप से यह बताने का कोई तरीका है कि क्या मेमोरी के विशेष ब्लॉक को फास्टएमएम द्वारा मुक्त नहीं किया गया था?


103

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

FastMM के एक दस्तावेज को पढ़ने के बाद मुझे पता है कि संस्करण 4.98 के बाद से हमारे पास प्रबंधक द्वारा अधिसूचित होने की संभावना है कि वे स्मृति आबंटन, फ़्रीज़ और रिअलोकेशन के बारे में जानकारी प्राप्त करें। उदाहरण के लिए OnDebugFreeMemFinishघटना हमारे लिए गुजर रही है PFullDebugBlockHeaderजिसमें उपयोगी सूचना है। एक चीज है PFullDebugBlockHeaderजो गायब है - सूचना यदि दिए गए ब्लॉक को एप्लिकेशन द्वारा मुक्त किया गया था।

जब तक OnDebugFreeMemFinishकेवल मुक्त ब्लॉक नहीं कहा जाता है? यह वह है जिसे मैं नहीं जानता और इसका पता लगाना चाहूंगा।

समस्या यह है कि यहां तक ​​कि हुकिंग में भी OnDebugFreeMemFinish घटना मैं यह पता लगाने में असमर्थ था कि ब्लॉक को मुक्त किया गया था या नहीं।

यहाँ एक उदाहरण है:

program MemLeakTest;

{$APPTYPE CONSOLE}

uses
  FastMM4, ExceptionLog, SysUtils;


procedure MemFreeEvent(APHeaderFreedBlock: PFullDebugBlockHeader; AResult: Integer);
begin
//This is executed at the end, but how should I know that this block should be freed
//by application? Unless this is executed ONLY for not freed blocks.
end;

procedure Leak;
var
  MyObject: TObject;
begin
  MyObject := TObject.Create;
end;

begin
  OnDebugFreeMemFinish := MemFreeEvent;
  Leak;
end.

मुझे जो याद आ रहा है वह कॉलबैक है:

procedure OnMemoryLeak(APointer: PFullDebugBlockHeader);

FastMM के स्रोत को ब्राउज़ करने के बाद मैंने देखा कि एक प्रक्रिया है:

procedure LogMemoryLeakOrAllocatedBlock(APointer: PFullDebugBlockHeader; IsALeak: Boolean);

जिसे खत्म किया जा सकता है, लेकिन शायद एक आसान तरीका है?


7
मैं हमेशा यह समझ चुका हूं कि FastMM केवल इस जांच को बहुत कम कार्रवाई के रूप में बना सकता है जिसे कार्यक्रम को परिभाषा के अनुसार करना चाहिए - इसलिए जब तक FastMM अपनी रिपोर्ट बनाता है तब तक आपका कोड समाप्त हो चुका होता है। एक आंशिक समाधान प्राप्त करने के लिए आप हमेशा उनके स्रोत में एक नज़र डाल सकते हैं कि कैसे स्मृति को आवंटित किया गया है।
ब्रायन फ्रॉस्ट

6
अपेक्षित लीक के रूप में रिपोर्ट की गई? क्या आपने इसे उम्मीद के मुताबिक रजिस्टर किया था। इसके अलावा, आप यह तय नहीं कर सकते कि स्मृति को शटडाउन तक लीक किया गया है, जब तक कि आप जटिल तर्क प्रदान नहीं करते हैं जो अपेक्षित जीवनकाल को समझता है।
डेविड हेफर्नन

6
यदि OnDebugFreeMemFinishयह कहा जाता है कि ब्लॉक को मुक्त कर दिया गया था। कोई OnMemoryLeakघटना नहीं है । ऐसी घटना कभी नहीं हो सकती है। फास्टएमएम क्या करता है, शटडाउन पर, यह निर्धारित करें कि जिन ब्लॉकों को मुक्त नहीं किया गया है, उन्हें लीक होना चाहिए। यह उससे पहले किसी रिसाव का पता नहीं लगा सकता।
डेविड हेफर्नन

12
जब भी FastMM मुझे बताता है कि कोई मेमोरी लीक है, मैं टूल्स को डाउन करता हूं और इसे तुरंत ठीक करता हूं। यदि आप ऐसा नहीं करते हैं तो आपको लीक को फिर से शुरू करने में मुश्किल होगी। यदि आप वास्तव में डेटाबेस में प्रवेश करना चाहते हैं तो आपको CheckBlocksOnShutdown फ़ंक्शन को देखना होगा। एक अन्य संभावित विस्तार बिंदु है, AppendEventLogलेकिन आपको मुझे संदेह है कि FastMM स्रोत को संशोधित करना होगा।
डेविड हेफर्नन

12
एर्म बस फ़ाइल को उठाएं, इसे पार्स करें और डीबी में डालें?
टोनी हॉपकिंसन

जवाबों:


2

यहां तक ​​कि अगर इस तरह के हैंडलर मौजूद हैं, तो यह लगभग बेकार हो जाएगा, क्योंकि डीबी सहित सब कुछ उस समय बंद हो जाएगा, जब फास्टएमएम साक्षात्कार का परीक्षण करेगा।

इसलिए, मेरा सुझाव है कि आप LogErrorsToFileइसमें FullDebugModeसशर्त के साथ चालू करें FastMM4Options.inc। यह आपको लीक के साथ एक टेक्स्ट फ़ाइल देगा, जिसे बाद में आप डीबी में पार्स और डाल सकते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.