unidade MemoryManager;
interface
PRocedure SnapCurrMemStatToFile(Nome do arquivo: string);
implementação
usa
Windows, SysUtils, TypInfo;
const
MaxCount = Alto(Palavra);
var
OldMemMgr: TMemoryManager;
ObjList: array[0..MaxCount] do ponteiro;
FreeInList: Inteiro = 0;
GetMemCount: Inteiro = 0;
FreeMemCount: Inteiro = 0;
ReallocMemCount: Inteiro = 0;
procedimento AddToList(P:Ponteiro);
começar
se FreeInList > High(ObjList) então
começar
MessageBox(0, '内存管理监视器指针列表溢出,请增大列表项数!', '内存管理监视器', mb_ok);
Saída;
fim;
ObjList[FreeInList] := P;
Inc(FreeInList);
fim;
procedimento RemoveFromList(P:Ponteiro);
var
Eu: Inteiro;
começar
para I := 0 para FreeInList - 1 faça
se ListaObj[I] = P então
começar
Dez(FreeInList);
Move(ObjList[I + 1], ObjList[I], (FreeInList - I) * SizeOf(Pointer));
Saída;
fim;
fim;
procedimento SnapCurrMemStatToFile (Nome do arquivo: string);
const
CAMPO_LARGURA = 20;
var
OutFile: TextFile;
I, CurrFree, BlockSize: Inteiro;
HeapStatus: THeapStatus;
Item: TObject;
ptd: PTypeData;
ppi: PPropInfo;
saída do procedimento (Texto: string; Valor: inteiro);
começar
Writeln(OutFile, Texto: FIELD_WIDTH, Valor div 1024, ' KB(', Valor, ' Byte)');
fim;
começar
AssignFile(OutFile, Nome do arquivo);
tentar
se FileExists (nome do arquivo) então
começar
Anexar(OutFile);
Writeln(OutFile);
fim
outro
Reescrever(OutFile);
CurrFree := FreeInList;
HeapStatus := GetHeapStatus; { 局部堆状态 }
com HeapStatus faça
começar
Writeln(OutFile, '===== ', ExtractFileName(ParamStr(0)), ',', DateTimeToStr(Agora), ' =====');
Writeln(OutArquivo);
Output('可用地址空间: ', TotalAddrSpace);
Output('未提交部分: ', TotalUncommited);
Output('已提交部分: ', TotalCommitted);
Output('空闲部分 : ', TotalFree);
Output('已分配部分: ', TotalAllocated);
Output('全部小空闲内存块: ', FreeSmall);
Output('全部大空闲内存块: ', FreeBig);
Output('其它未用内存块: ', Não utilizado);
Output('内存管理器消耗: ', Sobrecarga);
Writeln(OutFile, '地址空间载入: ':FIELD_WIDTH, div TotalAllocated (div 100TotalAddrSpace), '%');
fim;
Writeln(OutFile);
Writeln(OutFile, Format('当前出现 %d 处内存漏洞 :', [GetMemCount - FreeMemCount]));
para I := 0 para CurrFree - 1 do
começar
Write(OutFile, I: 4, ') ', IntToHex(Cardinal(ObjList[I]), 16), ' - ');
Tamanho do bloco := PDWORD(DWORD(ObjList[I]) - 4)^;
Write(OutFile, BlockSize: 4, '($' + IntToHex(BlockSize, 4) + ')字节', ' - ');
tentar
Item := TObject(ObjList[I]);
if PTypeInfo(Item.ClassInfo).Kind <> tkClass então {técnica de informação de tipo}
write(OutFile, '不是对象')
outro
começar
ptd := GetTypeData(PTypeInfo(Item.ClassInfo));
ppi := GetPropInfo(PTypeInfo(Item.ClassInfo), 'Nome'); { onde está TComponent }
se ppi <> nulo então
começar
write(OutFile, GetStrProp(Item, ppi));
write(OutArquivo, ' : ');
fim
outro
write(OutFile, '(未命名): ');
Write(OutFile, Item.ClassName, ' (', ptd.ClassType.InstanceSize,
' 字节) - In ', ptd.UnitName, '.pas');
fim
exceto
na exceção faça
write(OutFile, '不是对象');
fim;
writeln(OutFile);
fim;
finalmente
FecharArquivo(SaídaArquivo);
fim;
fim;
função NewGetMem (Tamanho: Inteiro): Ponteiro;
começar
Inc(GetMemCount);
Resultado:= OldMemMgr.GetMem(Tamanho);
AddToList(Resultado);
fim;
função NewFreeMem (P: Ponteiro): Inteiro;
começar
Inc(FreeMemCount);
Resultado:= OldMemMgr.FreeMem(P);
RemoveFromList(P);
fim;
função NewReallocMem (P: Ponteiro; Tamanho: Inteiro): Ponteiro;
começar
Inc(ReallocMemCount);
Resultado:= OldMemMgr.ReallocMem(P, Tamanho);
RemoveFromList(P);
AddToList(Resultado);
fim;
const
NewMemMgr: TMemoryManager = (
GetMem: NewGetMem;
FreeMem: NovoFreeMem;
ReallocMem: NewReallocMem);
inicialização
GetMemoryManager(OldMemMgr);
SetMemoryManager(NewMemMgr);
finalização
SetMemoryManager(OldMemMgr);
if (GetMemCount - FreeMemCount) <> 0 então
SnapCurrMemStatToFile(ExtractFileDir(ParamStr(0)) + '/Memory.Log');
fim.