如何获得Delphi程序使用的内存
我知道如何使用GlobalMemoryStatusEx获得系统内存的使用,但是这告诉我整个操作系统正在使用什么。
我真的希望我的程序能够报告已经分配和正在使用的内存。
在我的Delphi 2009程序中有没有办法调用Windows函数或者某个FastMM函数来查找单独由我的程序分配的内存?
重温我的问题,我现在已经通过@apenwarr将我接受的答案改为GetMemoryManagerState答案。 它产生了与我曾经使用过的GetHeapStatus函数(现在不推荐使用)相同的结果,而GetProcessMemoryInfo.WorkingSetSize给出了一个非常不同的结果。
您可以从Delphi运行时获得有用的内存使用信息,而不使用任何直接的Win32调用:
function MemoryUsed: cardinal; var st: TMemoryManagerState; sb: TSmallBlockTypeState; begin GetMemoryManagerState(st); result := st.TotalAllocatedMediumBlockSize + st.TotalAllocatedLargeBlockSize; for sb in st.SmallBlockTypeStates do begin result := result + sb.UseableBlockSize * sb.AllocatedBlockCount; end; end;
关于这个方法最好的事情是严格的跟踪:当你分配内存的时候,它会上升,当你释放内存的时候,它会立即下降。 我在运行每个unit testing之前和之后使用这个,所以我可以告诉哪个testing正在泄漏内存(例如)。
从我的旧博客文章 。
想知道你的程序使用了多less内存? 这个delphifunction将做的伎俩。
uses psAPI; {...} function CurrentProcessMemory: Cardinal; var MemCounters: TProcessMemoryCounters; begin MemCounters.cb := SizeOf(MemCounters); if GetProcessMemoryInfo(GetCurrentProcess, @MemCounters, SizeOf(MemCounters)) then Result := MemCounters.WorkingSetSize else RaiseLastOSError; end;
不知道我在哪里得到了这个的基本知识,但我添加了一些更好的error handling,并将其作为一个函数。 WorkingSetSize是当前使用的内存量。 您可以使用类似的代码来获取当前进程(或任何进程)的其他值。 您将需要在您的使用声明中包含psAPI。
PROCESS_MEMORY_COUNTERSlogging包括:
- PageFaultCount
- PeakWorkingSetSize
- WorkingSetSize
- QuotaPeakPagedPoolUsage
- QuotaPagedPoolUsage
- QuotaPeakNonPagedPoolUsage
- QuotaNonPagedPoolUsage
- PagefileUsage
- PeakPagefileUsage
您可以在任务pipe理器或进程资源pipe理器中find所有这些值。
我写了这个小函数来返回当前进程(app)的内存使用情况:
function ProcessMemory: longint; var pmc: PPROCESS_MEMORY_COUNTERS; cb: Integer; begin // Get the used memory for the current process cb := SizeOf(TProcessMemoryCounters); GetMem(pmc, cb); pmc^.cb := cb; if GetProcessMemoryInfo(GetCurrentProcess(), pmc, cb) then Result:= Longint(pmc^.WorkingSetSize); FreeMem(pmc); end;
从SourceForge下载完整的FastMM4软件包时,您可以查看如何使用FastMM与Demos中包含的UsageTrackerDemo项目的示例。
对于Win32 API的方式,你需要GetProcessMemoryInfo函数。 这里是MSDN页面的一个例子,但代码是用C ++编写的。 我想你也可以把它转换成Delphi。 你所看到的可能是所谓的“工作集大小”。
#include <windows.h> #include <stdio.h> #include <psapi.h> void PrintMemoryInfo( DWORD processID ) { HANDLE hProcess; PROCESS_MEMORY_COUNTERS pmc; // Print the process identifier. printf( "\nProcess ID: %u\n", processID ); // Print information about the memory usage of the process. hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID ); if (NULL == hProcess) return; if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) ) { printf( "\tPageFaultCount: 0x%08X\n", pmc.PageFaultCount ); printf( "\tPeakWorkingSetSize: 0x%08X\n", pmc.PeakWorkingSetSize ); printf( "\tWorkingSetSize: 0x%08X\n", pmc.WorkingSetSize ); printf( "\tQuotaPeakPagedPoolUsage: 0x%08X\n", pmc.QuotaPeakPagedPoolUsage ); printf( "\tQuotaPagedPoolUsage: 0x%08X\n", pmc.QuotaPagedPoolUsage ); printf( "\tQuotaPeakNonPagedPoolUsage: 0x%08X\n", pmc.QuotaPeakNonPagedPoolUsage ); printf( "\tQuotaNonPagedPoolUsage: 0x%08X\n", pmc.QuotaNonPagedPoolUsage ); printf( "\tPagefileUsage: 0x%08X\n", pmc.PagefileUsage ); printf( "\tPeakPagefileUsage: 0x%08X\n", pmc.PeakPagefileUsage ); } CloseHandle( hProcess ); } int main( ) { // Get the list of process identifiers. DWORD aProcesses[1024], cbNeeded, cProcesses; unsigned int i; if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) ) return 1; // Calculate how many process identifiers were returned. cProcesses = cbNeeded / sizeof(DWORD); // Print the memory usage for each process for ( i = 0; i < cProcesses; i++ ) PrintMemoryInfo( aProcesses[i] ); return 0; }