Je sais comment utiliser la mémoire système à l'aide de GlobalMemoryStatusEx, mais cela me dit ce que l'OS entier utilise.
Je veux vraiment que mon programme indique la quantité de mémoire qu'il a allouée et utilise.
Existe-t-il un moyen dans mon programme Delphi 2009 d'appeler une fonction Windows ou peut-être une fonction FastMM pour trouver la mémoire qui a été allouée par mon programme seul?
Revisitant ma question, j'ai maintenant changé ma réponse acceptée en réponse GetMemoryManagerState par @apenwarr. Il a produit des résultats identiques à la fonction GetHeapStatus (maintenant obsolète) que j'avais l'habitude d'utiliser, tandis que GetProcessMemoryInfo.WorkingSetSize a donné un résultat très différent.
Vous pouvez obtenir des informations utiles sur l'utilisation de la mémoire à partir du runtime Delphi sans utiliser d'appels Win32 directs:
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;
La meilleure chose à propos de cette méthode est qu'elle est strictement suivie: lorsque vous allouez de la mémoire, elle augmente et lorsque vous désallouez de la mémoire, elle diminue immédiatement du même montant. Je l'utilise avant et après l'exécution de chacun de mes tests unitaires, afin que je puisse dire quel test fuit la mémoire (par exemple).
À partir d'un ancien article de blog .
Vous voulez savoir combien de mémoire votre programme utilise? Cette fonction Delphi fera l'affaire.
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;
Je ne sais pas où j'ai obtenu les bases de cela, mais j'ai ajouté une meilleure gestion des erreurs et en ai fait une fonction. WorkingSetSize est la quantité de mémoire actuellement utilisée. Vous pouvez utiliser un code similaire pour obtenir d'autres valeurs pour le processus en cours (ou tout autre processus). Vous devrez inclure psAPI dans votre déclaration d'utilisations.
L'enregistrement PROCESS_MEMORY_COUNTERS comprend:
Vous pouvez trouver toutes ces valeurs dans le Gestionnaire des tâches ou l'Explorateur de processus.
J'ai écrit cette petite fonction pour renvoyer l'utilisation actuelle de la mémoire du processus (application):
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;
Vous pouvez consulter un exemple sur la façon d'utiliser FastMM avec le projet UsageTrackerDemo fourni avec les démos lorsque vous téléchargez le bundle FastMM4 complet depuis SourceForge.
Conversion du code Gant C++, en application console dans Delphi:
program MemoryProcessCMD;
{* Based in Gant(https://stackoverflow.com/users/12460/gant) code*}
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
psapi,
Windows;
procedure PrintMemoryInfo(processID: DWORD);
var
hProcess: THandle;
pmc: PROCESS_MEMORY_COUNTERS;
total: DWORD;
begin
// Print the process identifier.
Writeln(format('Process ID: %d', [processID]));
// Print information about the memory usage of the process.
hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, FALSE,
processID);
if (hProcess = 0) then
begin
exit;
end;
if (GetProcessMemoryInfo(hProcess, @pmc, SizeOf(pmc))) then
begin
Writeln(format(#09'PageFaultCount: 0x%.8X', [pmc.PageFaultCount]));
Writeln(format(#09'PeakWorkingSetSize: 0x%.8X', [pmc.PeakWorkingSetSize]));
Writeln(format(#09'WorkingSetSize: 0x%.8X', [pmc.WorkingSetSize]));
Writeln(format(#09'QuotaPeakPagedPoolUsage: 0x%.8X',
[pmc.QuotaPeakPagedPoolUsage]));
Writeln(format(#09'QuotaPagedPoolUsage: 0x%.8X',
[pmc.QuotaPagedPoolUsage]));
Writeln(format(#09'QuotaPeakNonPagedPoolUsage: 0x%.8X',
[pmc.QuotaPeakNonPagedPoolUsage]));
Writeln(format(#09'QuotaNonPagedPoolUsage: 0x%.8X',
[pmc.QuotaNonPagedPoolUsage]));
Writeln(format(#09'PagefileUsage: 0x%.8X', [pmc.PagefileUsage]));
Writeln(format(#09'PeakPagefileUsage: 0x%.8X', [pmc.PeakPagefileUsage]));
Writeln(format(#09'PagefileUsage: 0x%.8X', [pmc.PagefileUsage]));
end;
CloseHandle(hProcess);
end;
var
aProcesses: array [0 .. 1024] of DWORD;
cbNeeded, cProcesses: DWORD;
i: Integer;
begin
try
// Get the list of process identifiers.
if (not EnumProcesses(@aProcesses, SizeOf(aProcesses), &cbNeeded)) then
halt(1);
// Calculate how many process identifiers were returned.
cProcesses := cbNeeded div SizeOf(DWORD);
// Print the memory usage for each process
for i := 0 to cProcesses - 1 do
begin
PrintMemoryInfo(aProcesses[i]);
end;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
Pour l'API Win32, vous avez besoin de la fonction GetProcessMemoryInfo . Voici un exemple de page MSDN mais le code est en C++. Je pense que vous pouvez également le convertir en Delphi. Ce que vous recherchez est probablement appelé "Taille de l'ensemble de travail".
#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;
}