Bug 1007534 - Part 4: Save a memory report when close to OOM. r=bsmedberg

This commit is contained in:
David Major 2014-08-30 17:21:22 +12:00
parent 27a45e66c7
commit 7d5ca445e0

View File

@ -30,6 +30,11 @@
#include "nsXPCOMPrivate.h"
#include "mozilla/ChaosMode.h"
#ifdef MOZ_CRASHREPORTER
#include "nsServiceManagerUtils.h"
#include "nsICrashReporter.h"
#endif
#ifdef XP_LINUX
#include <sys/time.h>
#include <sys/resource.h>
@ -386,6 +391,34 @@ nsThread::ThreadFunc(void* aArg)
//-----------------------------------------------------------------------------
#ifdef MOZ_CRASHREPORTER
// Tell the crash reporter to save a memory report if our heuristics determine
// that an OOM failure is likely to occur soon.
static bool SaveMemoryReportNearOOM()
{
bool needMemoryReport = false;
#ifdef XP_WIN // XXX implement on other platforms as needed
const size_t LOWMEM_THRESHOLD_VIRTUAL = 200 * 1024 * 1024;
MEMORYSTATUSEX statex;
statex.dwLength = sizeof(statex);
if (GlobalMemoryStatusEx(&statex)) {
if (statex.ullAvailVirtual < LOWMEM_THRESHOLD_VIRTUAL) {
needMemoryReport = true;
}
}
#endif
if (needMemoryReport) {
nsCOMPtr<nsICrashReporter> cr =
do_GetService("@mozilla.org/toolkit/crash-reporter;1");
cr->SaveMemoryReport();
}
return needMemoryReport;
}
#endif
#ifdef MOZ_CANARY
int sCanaryOutputFD = -1;
#endif
@ -729,6 +762,27 @@ nsThread::ProcessNextEvent(bool aMayWait, bool* aResult)
}
}
#ifdef MOZ_CRASHREPORTER
if (MAIN_THREAD == mIsMainThread && !ShuttingDown()) {
// Keep an eye on memory usage (cheap, ~7ms) somewhat frequently,
// but save memory reports (expensive, ~75ms) less frequently.
const size_t LOW_MEMORY_CHECK_SECONDS = 30;
const size_t LOW_MEMORY_SAVE_SECONDS = 3 * 60;
static TimeStamp nextCheck = TimeStamp::NowLoRes()
+ TimeDuration::FromSeconds(LOW_MEMORY_CHECK_SECONDS);
TimeStamp now = TimeStamp::NowLoRes();
if (now >= nextCheck) {
if (SaveMemoryReportNearOOM()) {
nextCheck = now + TimeDuration::FromSeconds(LOW_MEMORY_SAVE_SECONDS);
} else {
nextCheck = now + TimeDuration::FromSeconds(LOW_MEMORY_CHECK_SECONDS);
}
}
}
#endif
bool notifyMainThreadObserver =
(MAIN_THREAD == mIsMainThread) && sMainThreadObserver;
if (notifyMainThreadObserver) {