2016-11-25 44 views
1

正如主题所说,为什么windbg无法看到在delphi中分配的任何内存?例如,堆不提供任何东西,而有意创建的10MB内存泄漏仅用于测试目的。为什么Windbg无法看到在delphi中创建的内存泄漏?

delphi如何分配内存而不从堆中取出内存?

+0

它是否列出,如果你分配它与HeapAlloc? –

+0

Delphi中的对象通常不直接用HeapAlloc分配,但这些对象仍然在堆上创建,因为它们不能在其他地方创建。 – moose

+0

我很清楚Delphi的内存分配是如何工作的,最近写了一个包含'HeapAlloc'的内存管理器。我的观点是,我怀疑WinDbg是否只报告通过'HeapAlloc'分配的堆内存。 –

回答

8

!heap作品与内存调用分配给HeapAllocHeapReAlloc等德尔福的默认内存管理器使用VirtualAlloc,然后实现它自己的子分配器。所以,德尔福的内存管理器正在执行类似于HeapAlloc的任务。这意味着,但是Delphi的默认内存管理器分配的内存对!heap不可见。

如果你真的想要使用WinDbg和!heap那么你可以用一个内置于HeapAlloc的Delphi内存管理器代替它。也许这将符合您的调试要求。我不知道是什么驱使你去WinDbg和!heap

或者,如果你想有一个本地德尔福的方式找到泄漏,您可以使用工具,如FastMM4(完整版本,而不是建立在德尔福)或madExcept 4.

举一个简单的内存管理器替代的示范建立在HeapAlloc我提供这个单位:

unit HeapAllocMM; 

interface 

implementation 

uses 
    Windows; 

function GetMem(Size: NativeInt): Pointer; 
begin 
    Result := HeapAlloc(0, 0, size); 
end; 

function FreeMem(P: Pointer): Integer; 
begin 
    HeapFree(0, 0, P); 
    Result := 0; 
end; 

function ReallocMem(P: Pointer; Size: NativeInt): Pointer; 
begin 
    Result := HeapReAlloc(0, 0, P, Size); 
end; 

function AllocMem(Size: NativeInt): Pointer; 
begin 
    Result := GetMem(Size); 
    if Assigned(Result) then begin 
    FillChar(Result^, Size, 0); 
    end; 
end; 

function RegisterUnregisterExpectedMemoryLeak(P: Pointer): Boolean; 
begin 
    Result := False; 
end; 

const 
    MemoryManager: TMemoryManagerEx = (
    GetMem: GetMem; 
    FreeMem: FreeMem; 
    ReallocMem: ReallocMem; 
    AllocMem: AllocMem; 
    RegisterExpectedMemoryLeak: RegisterUnregisterExpectedMemoryLeak; 
    UnregisterExpectedMemoryLeak: RegisterUnregisterExpectedMemoryLeak 
); 

initialization 
    SetMemoryManager(MemoryManager); 

end. 

名单,由于在.dpr文件的使用条款的第一单元。一旦你完成了这个,WinDbg !heap应该开始看到你的Delphi堆分配。

+0

事实上,无论是与德尔菲有关的不可靠的驱使我到Windbg,UDM和类似的工具。但这种做法显然是死路一条。替换Delphi内存管理器...可能是一个好主意,但恐怕这需要几个月才能完成。购买一些第三方工具从来没有像预期的那样工作。 – moose

+4

用于调试的'HeapAlloc' Delphi MM可以在5分钟内完成。 FastMM和madExcept都是非常好的检漏工具。 FastMM不会花你一分钱。 madExcept价格便宜,质量很棒。 –