зеркало из https://github.com/mozilla/gecko-dev.git
fixes bug 328068 "gather memory usage data for load events" r=bryner
This commit is contained in:
Родитель
0f2e2396b0
Коммит
8f036a01aa
|
@ -48,6 +48,102 @@
|
|||
#include "nsIDOMWindow.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if defined(__linux)
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
static FILE *sProcFP;
|
||||
static void GetMemUsage_Shutdown() {
|
||||
if (sProcFP) {
|
||||
fclose(sProcFP);
|
||||
sProcFP = NULL;
|
||||
}
|
||||
}
|
||||
#elif defined(XP_WIN)
|
||||
#include <windows.h>
|
||||
#include <psapi.h>
|
||||
typedef BOOL (WINAPI * GETPROCESSMEMORYINFO_FUNC)(
|
||||
HANDLE process, PPROCESS_MEMORY_COUNTERS counters, DWORD cb);
|
||||
static HMODULE sPSModule;
|
||||
static HANDLE sProcess;
|
||||
static GETPROCESSMEMORYINFO_FUNC sGetMemInfo;
|
||||
static void GetMemUsage_Shutdown() {
|
||||
if (sProcess) {
|
||||
CloseHandle(sProcess);
|
||||
sProcess = NULL;
|
||||
}
|
||||
if (sPSModule) {
|
||||
FreeLibrary(sPSModule);
|
||||
sPSModule = NULL;
|
||||
}
|
||||
sGetMemInfo = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct MemUsage {
|
||||
PRInt64 total;
|
||||
PRInt64 resident;
|
||||
};
|
||||
|
||||
// This method should be incorporated into NSPR
|
||||
static PRBool GetMemUsage(MemUsage *result)
|
||||
{
|
||||
PRBool setResult = PR_FALSE;
|
||||
#if defined(__linux)
|
||||
// Read /proc/<pid>/statm, and look at the first and second fields, which
|
||||
// report the program size and the number of resident pages for this process,
|
||||
// respectively.
|
||||
|
||||
char buf[256];
|
||||
if (!sProcFP) {
|
||||
pid_t pid = getpid();
|
||||
snprintf(buf, sizeof(buf), "/proc/%d/statm", pid);
|
||||
sProcFP = fopen(buf, "rb");
|
||||
}
|
||||
if (sProcFP) {
|
||||
int vmsize, vmrss;
|
||||
|
||||
int count = fscanf(sProcFP, "%d %d", &vmsize, &vmrss);
|
||||
rewind(sProcFP);
|
||||
|
||||
if (count == 2) {
|
||||
static int ps = getpagesize();
|
||||
result->total = PRInt64(vmsize) * ps;
|
||||
result->resident = PRInt64(vmrss) * ps;
|
||||
setResult = PR_TRUE;
|
||||
}
|
||||
}
|
||||
#elif defined(XP_WIN)
|
||||
// Use GetProcessMemoryInfo, which only works on WinNT and later.
|
||||
|
||||
if (!sGetMemInfo) {
|
||||
sPSModule = LoadLibrary("psapi.dll");
|
||||
if (sPSModule) {
|
||||
sGetMemInfo = (GETPROCESSMEMORYINFO_FUNC)
|
||||
GetProcAddress(sPSModule, "GetProcessMemoryInfo");
|
||||
if (sGetMemInfo)
|
||||
sProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
|
||||
FALSE, GetCurrentProcessId());
|
||||
// Don't leave ourselves partially initialized.
|
||||
if (!sProcess)
|
||||
GetMemUsage_Shutdown();
|
||||
}
|
||||
}
|
||||
if (sGetMemInfo) {
|
||||
PROCESS_MEMORY_COUNTERS pmc;
|
||||
if (sGetMemInfo(sProcess, &pmc, sizeof(pmc))) {
|
||||
result->total = PRInt64(pmc.PagefileUsage);
|
||||
result->resident = PRInt64(pmc.WorkingSetSize);
|
||||
setResult = PR_TRUE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return setResult;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static nsLoadCollector *gLoadCollector = nsnull;
|
||||
|
||||
NS_IMPL_ISUPPORTS2(nsLoadCollector,
|
||||
|
@ -150,6 +246,14 @@ nsLoadCollector::OnStateChange(nsIWebProgress *webProgress,
|
|||
rv = props->SetPropertyAsUint64(NS_LITERAL_STRING("loadtime"), loadTime);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
MemUsage mu;
|
||||
if (GetMemUsage(&mu)) {
|
||||
rv = props->SetPropertyAsUint64(NS_LITERAL_STRING("memtotal"), mu.total);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = props->SetPropertyAsUint64(NS_LITERAL_STRING("memresident"), mu.resident);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
nsMetricsService *ms = nsMetricsService::get();
|
||||
rv = ms->LogEvent(NS_LITERAL_STRING("load"), props);
|
||||
|
||||
|
@ -220,6 +324,8 @@ nsLoadCollector::Shutdown()
|
|||
// See comments in nsWindowCollector::Shutdown about why we don't
|
||||
// null out gLoadCollector here.
|
||||
gLoadCollector->Release();
|
||||
|
||||
GetMemUsage_Shutdown();
|
||||
}
|
||||
|
||||
nsLoadCollector::~nsLoadCollector()
|
||||
|
|
Загрузка…
Ссылка в новой задаче