メモリブロックが解放されなかったかどうかを検出しようとしています。もちろん、マネージャーはダイアログボックスまたはログファイルでそれを通知しますが、データベースに結果を保存したい場合はどうなりますか?たとえば、データベーステーブルに、特定のブロックを割り当てたルーチンの名前を付けたいと思います。
FastMMのドキュメントを読んだ後、バージョン4.98以降、メモリの割り当て、解放、再割り当てが発生すると、マネージャから通知を受ける可能性があることがわかりました。たとえば、OnDebugFreeMemFinish
イベントはPFullDebugBlockHeader
有用な情報を含むaに渡されます。PFullDebugBlockHeader
不足していることが1つあります。指定されたブロックがアプリケーションによって解放された場合の情報です。
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);
これはオーバーライドできますが、もっと簡単な方法があるかもしれませんか?
OnDebugFreeMemFinish
が呼び出された場合は、ブロックが解放されたことを意味します。OnMemoryLeak
イベントはありません。そのような出来事は決してあり得なかったでしょう。FastMMが行うことは、シャットダウン時に、解放されていないブロックはすべてリークでなければならないことを決定することです。それより前にリークを検出することはできません。
AppendEventLog
ありますが、私は疑わしいFastMMソースを変更する必要があります。