Jak uzyskać pamięć używaną przez program Delphi
Wiem, jak uzyskać użycie pamięci systemowej za pomocą GlobalMemoryStatusEx, ale to mówi mi, czego używa cały system operacyjny.
Naprawdę chcę, aby mój program raportował, ile pamięci sam przydzielił i używa.
Czy Jest jakiś sposób w moim programie Delphi 2009, aby wywołać funkcję Windows lub może jakąś funkcję FastMM, aby dowiedzieć się, że pamięć została przydzielona tylko przez mój program?
[[0]] Revisiting my question, I have now changed my accepted answer to the GetMemoryManagerState answer by @apenwarr. To produkowane identyczne wyniki do funkcji GetHeapStatus (teraz przestarzałe), że kiedyś używać, podczas gdy GetProcessMemoryInfo.WorkingSetSize dało zupełnie inny wynik.
5 answers
Możesz uzyskać przydatne informacje o użyciu pamięci z środowiska uruchomieniowego Delphi bez użycia bezpośrednich wywołań Win32:
unit X;
uses FastMM4; //include this or method will return 0.
....
function GetMemoryUsed: UInt64;
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;
Najlepszą rzeczą w tej metodzie jest to, że jest ściśle śledzona: kiedy przydzielasz pamięć, idzie ona w górę, a kiedy dealokujesz pamięć, od razu spada o tę samą ilość. Używam tego przed i po uruchomieniu każdego z moich testów jednostkowych, więc mogę stwierdzić ,który test jest wyciek pamięci(na przykład).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-04-14 15:25:27
Chcesz wiedzieć, ile pamięci zużywa twój program? Ta funkcja Delphi załatwi sprawę.
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;
Nie jestem pewien, skąd mam podstawy tego, ale dodałem do niego lepszą obsługę błędów i zrobiłem z niej funkcję. WorkingSetSize to ilość aktualnie używanej pamięci. Możesz użyć podobnego kodu, aby uzyskać inne wartości dla bieżącego procesu (lub dowolnego procesu). Musisz uwzględnić psAPI w swoim oświadczeniu uses.
The PROCESS_MEMORY_COUNTERS zapis zawiera:
- PageFaultCount
- PeakWorkingSetSize
- WorkingSetSize
- QuotaPeakPagedPoolUsage
- QuotaPagedPoolUsage
- QuotaPeakNonPagedPoolUsage
- QuotaNonPagedPoolUsage
- PagefileUsage
- PeakPagefileUsage
Wszystkie te wartości można znaleźć w Menedżerze Zadań lub Eksploratorze procesów.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-14 08:26:14
Możesz spojrzeć na przykład jak używać FastMM z projektem UsageTrackerDemo, który jest dołączony do dema po pobraniu pełnego pakietu FastMM4 z SourceForge.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-13 02:08:34
Napisałem tę małą funkcję, aby zwrócić bieżące zużycie pamięci procesu (aplikacji):
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;
Dla interfejsu API Win32 potrzebna jest funkcja GetProcessMemoryInfo . Oto przykład ze strony MSDN ale kod jest w C++. Myślę, że można przekonwertować go do Delphi, jak również. To, czego szukasz, prawdopodobnie nazywa się " roboczym rozmiarem zestawu."
#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;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-13 01:34:22