Bug 789975 - Disable purging of MADV_FREE'd pages on MacOS when collecting RSS from Telemetry. r=njn

This commit is contained in:
Justin Lebar 2013-01-14 21:49:25 -05:00
Родитель 15102081e5
Коммит 59d800736b
3 изменённых файлов: 55 добавлений и 10 удалений

Просмотреть файл

@ -720,12 +720,23 @@ function getTreesByProcess(aProcessMemoryReports, aTreesByProcess,
// "ghost-windows" multi-reporters all the time. (Note that reports from // "ghost-windows" multi-reporters all the time. (Note that reports from
// these multi-reporters can reach here as single reports if they were in the // these multi-reporters can reach here as single reports if they were in the
// child process.) // child process.)
//
// Also ignore the resident-fast reporter; we use the vanilla resident
// reporter because it's more important that we get accurate results than
// that we avoid the (small) possibility of a long pause when loading
// about:memory.
//
// We don't show both resident and resident-fast because running the resident
// reporter can purge pages on MacOS, which affects the results of the
// resident-fast reporter. We don't want about:memory's results to be
// affected by the order of memory reporter execution.
function ignoreSingle(aUnsafePath) function ignoreSingle(aUnsafePath)
{ {
return (isSmapsPath(aUnsafePath) && !gVerbose && !aForceShowSmaps) || return (isSmapsPath(aUnsafePath) && !gVerbose && !aForceShowSmaps) ||
aUnsafePath.startsWith("compartments/") || aUnsafePath.startsWith("compartments/") ||
aUnsafePath.startsWith("ghost-windows/"); aUnsafePath.startsWith("ghost-windows/") ||
aUnsafePath == "resident-fast";
} }
function ignoreMulti(aMRName) function ignoreMulti(aMRName)

Просмотреть файл

@ -56,7 +56,7 @@ const MEM_HISTOGRAMS = {
"js-compartments/system": "MEMORY_JS_COMPARTMENTS_SYSTEM", "js-compartments/system": "MEMORY_JS_COMPARTMENTS_SYSTEM",
"js-compartments/user": "MEMORY_JS_COMPARTMENTS_USER", "js-compartments/user": "MEMORY_JS_COMPARTMENTS_USER",
"explicit": "MEMORY_EXPLICIT", "explicit": "MEMORY_EXPLICIT",
"resident": "MEMORY_RESIDENT", "resident-fast": "MEMORY_RESIDENT",
"vsize": "MEMORY_VSIZE", "vsize": "MEMORY_VSIZE",
"storage-sqlite": "MEMORY_STORAGE_SQLITE", "storage-sqlite": "MEMORY_STORAGE_SQLITE",
"images-content-used-uncompressed": "images-content-used-uncompressed":

Просмотреть файл

@ -242,6 +242,11 @@ static nsresult GetResident(int64_t *n)
return NS_OK; return NS_OK;
} }
static nsresult GetResidentFast(int64_t *n)
{
return GetResident(n);
}
#elif defined(XP_MACOSX) #elif defined(XP_MACOSX)
#include <mach/mach_init.h> #include <mach/mach_init.h>
@ -269,16 +274,17 @@ static nsresult GetVsize(int64_t *n)
return NS_OK; return NS_OK;
} }
static nsresult GetResident(int64_t *n) // If we're using jemalloc on Mac, we need to instruct jemalloc to purge the
// pages it has madvise(MADV_FREE)'d before we read our RSS in order to get
// an accurate result. The OS will take away MADV_FREE'd pages when there's
// memory pressure, so ideally, they shouldn't count against our RSS.
//
// Purging these pages can take a long time for some users (see bug 789975),
// so we provide the option to get the RSS without purging first.
static nsresult GetResident(int64_t *n, bool aDoPurge)
{ {
#ifdef HAVE_JEMALLOC_STATS #ifdef HAVE_JEMALLOC_STATS
// If we're using jemalloc on Mac, we need to instruct jemalloc to purge if (aDoPurge)
// the pages it has madvise(MADV_FREE)'d before we read our RSS. The OS
// will take away MADV_FREE'd pages when there's memory pressure, so they
// shouldn't count against our RSS.
//
// Purging these pages shouldn't take more than 10ms or so, but we want to
// keep an eye on it since GetResident() is called on each Telemetry ping.
{ {
Telemetry::AutoTimer<Telemetry::MEMORY_FREE_PURGED_PAGES_MS> timer; Telemetry::AutoTimer<Telemetry::MEMORY_FREE_PURGED_PAGES_MS> timer;
jemalloc_purge_freed_pages(); jemalloc_purge_freed_pages();
@ -293,6 +299,16 @@ static nsresult GetResident(int64_t *n)
return NS_OK; return NS_OK;
} }
static nsresult GetResidentFast(int64_t *n)
{
return GetResident(n, /* doPurge = */ false);
}
static nsresult GetResident(int64_t *n)
{
return GetResident(n, /* doPurge = */ true);
}
#elif defined(XP_WIN) #elif defined(XP_WIN)
#include <windows.h> #include <windows.h>
@ -325,6 +341,11 @@ static nsresult GetResident(int64_t *n)
return NS_OK; return NS_OK;
} }
static nsresult GetResidentFast(int64_t *n)
{
return GetResident(n);
}
#define HAVE_PRIVATE_REPORTER #define HAVE_PRIVATE_REPORTER
static nsresult GetPrivate(int64_t *n) static nsresult GetPrivate(int64_t *n)
{ {
@ -377,6 +398,18 @@ NS_FALLIBLE_MEMORY_REPORTER_IMPLEMENT(Resident,
"but it depends both on other processes being run and details of the OS " "but it depends both on other processes being run and details of the OS "
"kernel and so is best used for comparing the memory usage of a single " "kernel and so is best used for comparing the memory usage of a single "
"process at different points in time.") "process at different points in time.")
NS_FALLIBLE_MEMORY_REPORTER_IMPLEMENT(ResidentFast,
"resident-fast",
KIND_OTHER,
UNITS_BYTES,
GetResidentFast,
"This reporter measures the same value as the resident memory reporter, but "
"it tries to be as fast as possible, at the expense of accuracy. On most "
"platforms this is identical to the vanilla resident reporter, but on MacOS"
"in particular, this reporter may over-count our RSS. You should use "
"resident-fast where you care about latency of collection (e.g. in "
"telemetry). Otherwise you should use the regular resident reporter.")
#endif // HAVE_VSIZE_AND_RESIDENT_REPORTERS #endif // HAVE_VSIZE_AND_RESIDENT_REPORTERS
#ifdef HAVE_PAGE_FAULT_REPORTERS #ifdef HAVE_PAGE_FAULT_REPORTERS
@ -665,6 +698,7 @@ nsMemoryReporterManager::Init()
#ifdef HAVE_VSIZE_AND_RESIDENT_REPORTERS #ifdef HAVE_VSIZE_AND_RESIDENT_REPORTERS
REGISTER(Vsize); REGISTER(Vsize);
REGISTER(Resident); REGISTER(Resident);
REGISTER(ResidentFast);
#endif #endif
#ifdef HAVE_PAGE_FAULT_REPORTERS #ifdef HAVE_PAGE_FAULT_REPORTERS