Belirli bir bellek bloğunun FastMM tarafından serbest bırakılıp bırakılmadığını programlı olarak anlamanın bir yolu var mı?


103

Bir bellek bloğunun serbest bırakılıp bırakılmadığını tespit etmeye çalışıyorum. Tabii ki, yönetici bunu iletişim kutusu veya günlük dosyasıyla söylüyor, ancak sonuçları bir veritabanında saklamak istersem ne olur? Örneğin, bir veritabanı tablosunda, verilen blokları tahsis eden rutin isimleri olmasını istiyorum.

FastMM'nin bir belgesini okuduktan sonra, 4.98 sürümünden bu yana, bellek ayırmaları, serbest bırakmalar ve yeniden tahsisatlar hakkında yönetici tarafından bilgilendirilme olanağına sahip olduğumuzu biliyorum. Örneğin OnDebugFreeMemFinisholay bize PFullDebugBlockHeaderyararlı bilgiler içeren bir geçiyor . PFullDebugBlockHeaderEksik olan bir şey var - verilen blok uygulama tarafından serbest bırakılmışsa bilgi.

Sürece OnDebugFreeMemFinishsadece serbest bloklar için denir? Bu bilmediğim ve öğrenmek istediğim şey.

Sorun şu ki, OnDebugFreeMemFinisholaya takılırken bile bloğun serbest bırakılıp bırakılmadığını bulamadım.

İşte bir örnek:

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.

Eksik olduğum şey şöyle bir geri arama:

procedure OnMemoryLeak(APointer: PFullDebugBlockHeader);

FastMM kaynağına göz attıktan sonra bir prosedür olduğunu gördüm:

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

hangisi geçersiz kılınabilir, ama belki daha kolay bir yolu vardır?


7
FastMM'nin bu denetimi yalnızca programın - tanım gereği - yapması gereken ÇOK SON eylem olarak yapabileceğini her zaman anladım, bu nedenle FastMM raporunu hazırladığında kodunuz bitmiştir. Kısmi bir çözüm elde etmek için, ayrılan belleğin nasıl işaretlendiğini görmek için her zaman kaynaklarına bakabilirsiniz.
Brian Frost

6
Beklenen sızıntı olarak bildirildi mi? Beklendiği gibi kaydettiniz mi? Ayrıca, beklenen yaşam sürelerini anlayan karmaşık bir mantık sağlamadığınız sürece, belleğin kapanana kadar sızdırıldığına karar veremezsiniz.
David Heffernan

6
Eğer OnDebugFreeMemFinishçağrılırsa bu, bloğun serbest bırakıldığı anlamına gelir. OnMemoryLeakOlay yok . Asla böyle bir olay olamaz. FastMM'nin yaptığı, kapatma sırasında, serbest bırakılmamış blokların sızıntı olması gerektiğini belirlemektir. Bundan daha erken bir sızıntı tespit edemez.
David Heffernan

12
FastMM bana bir bellek sızıntısı olduğunu söylediğinde, araçları devre dışı bırakıp hemen düzeltirim. Bunu yapmazsanız, sızıntıyı yeniden üretmekte zorlanacaksınız. Veritabanına gerçekten giriş yapmak istiyorsanız, CheckBlocksOnShutdown işlevine bakmanız gerekir. Başka bir olası uzantı noktası, AppendEventLogancak şüphelendiğim FastMM kaynağını değiştirmeniz gerekecek.
David Heffernan

12
Erm sadece dosyayı alıp, ayrıştırıp DB'ye mi koyacak?
Tony Hopkinson

Yanıtlar:


2

Böyle bir işleyici mevcut olsa bile, DB dahil her şey FastMM sızıntı bildirdiğinde kapatılacağı için neredeyse yararsız olacaktır.

Bu yüzden, şartlı LogErrorsToFileifadelerle birlikte açmanızı öneririm . Bu size daha sonra ayrıştırıp DB'ye koyabileceğiniz sızıntıları olan bir metin dosyası verecektir.FullDebugModeFastMM4Options.inc

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.